From b333fa835dd9ff3a1b0dff0ce8142a2f03c368c7 Mon Sep 17 00:00:00 2001 From: Junyoung/Clare Jang <jjc9310@gmail.com> Date: Tue, 21 May 2024 04:22:22 -0400 Subject: [PATCH 1/8] Clean up proofs --- theories/Core/Completeness/FunctionCases.v | 70 ++++++--------- theories/Core/Completeness/LogicalRelation.v | 2 +- .../Completeness/LogicalRelation/Tactics.v | 10 +++ .../Core/Completeness/TermStructureCases.v | 88 ++++++++----------- theories/Core/Completeness/UniverseCases.v | 39 ++++---- theories/Core/Completeness/VariableCases.v | 74 +++++++++++++--- theories/_CoqProject | 3 +- 7 files changed, 155 insertions(+), 131 deletions(-) create mode 100644 theories/Core/Completeness/LogicalRelation/Tactics.v diff --git a/theories/Core/Completeness/FunctionCases.v b/theories/Core/Completeness/FunctionCases.v index 8ae92b3f..7e142ee5 100644 --- a/theories/Core/Completeness/FunctionCases.v +++ b/theories/Core/Completeness/FunctionCases.v @@ -1,4 +1,4 @@ -From Coq Require Import Morphisms_Relations RelationClasses SetoidTactics. +From Coq Require Import Morphisms_Relations Relation_Definitions RelationClasses. From Mcltt Require Import Base LibTactics. From Mcltt.Core Require Import Completeness.LogicalRelation Completeness.TermStructureCases System. Import Domain_Notations. @@ -52,11 +52,9 @@ Proof with intuition. pose (env_relΓA0 := env_relΓA). inversion_by_head (per_ctx_env env_relΓA); subst. handle_per_ctx_env_irrel. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption tail_rel H). + (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ Type@i }}}); subst. match goal with @@ -104,13 +102,11 @@ Proof with intuition. pose (env_relΔA0 := env_relΔA). inversion_by_head (per_ctx_env env_relΔA); subst. handle_per_ctx_env_irrel. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). assert {{ Dom o' ≈ o' ∈ tail_rel }} by (etransitivity; [symmetry|]; eassumption). - (on_all_hyp: fun H => destruct_rel_by_assumption tail_rel H). + (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ Type@i }}}); subst. match goal with @@ -159,11 +155,9 @@ Proof with intuition. pose (env_relΓA0 := env_relΓA). inversion_by_head (per_ctx_env env_relΓA); subst. handle_per_ctx_env_irrel. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption tail_rel H). + (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ Type@i }}}); subst. match goal with @@ -209,12 +203,10 @@ Proof with intuition. pose (env_relΔA0 := env_relΔA). inversion_by_head (per_ctx_env env_relΔA); subst. handle_per_ctx_env_irrel. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). - (on_all_hyp: fun H => destruct_rel_by_assumption tail_rel H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + (on_all_hyp: destruct_rel_by_assumption tail_rel). eexists ?[elem_rel]. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; eauto with typeclass_instances. @@ -248,12 +240,10 @@ Proof with intuition. destruct_conjs. pose (env_relΓ0 := env_relΓ). handle_per_ctx_env_irrel. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. assert (equiv_p'_p' : env_relΓ p' p') by (etransitivity; [symmetry |]; eauto). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ Π A B }}}); subst. match goal with @@ -264,12 +254,12 @@ Proof with intuition. destruct_by_head rel_exp. functional_eval_rewrite_clear. assert (in_rel m1 m2) by (etransitivity; [| symmetry]; eauto). - (on_all_hyp: fun H => destruct_rel_by_assumption in_rel H). - (on_all_hyp_rev: fun H => destruct_rel_by_assumption in_rel H). + (on_all_hyp: destruct_rel_by_assumption in_rel). + (on_all_hyp_rev: destruct_rel_by_assumption in_rel). handle_per_univ_elem_irrel. eexists ?[elem_rel]. split; [> econstructor; only 1-2: econstructor ..]. - 1,3: repeat econstructor; eauto. + 1,3: repeat econstructor. all: eauto. Qed. @@ -286,12 +276,10 @@ Proof with intuition. pose (env_relΓ0 := env_relΓ). pose (env_relΔ0 := env_relΔ). handle_per_ctx_env_irrel. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΔ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ Π A B }}}); subst. match goal with @@ -301,11 +289,11 @@ Proof with intuition. handle_per_univ_elem_irrel. destruct_by_head rel_exp. functional_eval_rewrite_clear. - (on_all_hyp_rev: fun H => destruct_rel_by_assumption in_rel H). + (on_all_hyp_rev: destruct_rel_by_assumption in_rel). eexists ?[elem_rel]. split; [> econstructor; only 1-2: econstructor ..]. - 1,3,8,9: repeat econstructor; eauto. - 5: econstructor. + 1,3,8,9: repeat econstructor. + 15: econstructor. all: eauto. Qed. @@ -322,11 +310,9 @@ Proof with intuition. pose (env_relΓA0 := env_relΓA). inversion_by_head (per_ctx_env env_relΓA); subst. handle_per_ctx_env_irrel. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption tail_rel H). + (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. handle_per_univ_elem_irrel. destruct_by_head rel_exp. @@ -345,11 +331,9 @@ Proof with intuition. intros * [env_relΓ]. destruct_conjs. pose (env_relΓ0 := env_relΓ). - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ Π A B }}}); subst. match goal with @@ -361,7 +345,7 @@ Proof with intuition. eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption in_rel H). + (on_all_hyp: destruct_rel_by_assumption in_rel). econstructor; eauto. do 2 econstructor; eauto; econstructor; eauto. econstructor. diff --git a/theories/Core/Completeness/LogicalRelation.v b/theories/Core/Completeness/LogicalRelation.v index 5c8daddf..7bf4b691 100644 --- a/theories/Core/Completeness/LogicalRelation.v +++ b/theories/Core/Completeness/LogicalRelation.v @@ -1 +1 @@ -From Mcltt.Core.Completeness Require Export LogicalRelation.Definitions LogicalRelation.Lemmas. +From Mcltt.Core.Completeness Require Export LogicalRelation.Definitions LogicalRelation.Lemmas LogicalRelation.Tactics. diff --git a/theories/Core/Completeness/LogicalRelation/Tactics.v b/theories/Core/Completeness/LogicalRelation/Tactics.v new file mode 100644 index 00000000..89400fc2 --- /dev/null +++ b/theories/Core/Completeness/LogicalRelation/Tactics.v @@ -0,0 +1,10 @@ +Ltac eexists_rel_exp := + eexists; + eexists; [eassumption |]; + eexists. + +Ltac eexists_rel_subst := + eexists; + eexists; [eassumption |]; + eexists; + eexists; [eassumption |]. diff --git a/theories/Core/Completeness/TermStructureCases.v b/theories/Core/Completeness/TermStructureCases.v index bfd8c44d..db0a81b7 100644 --- a/theories/Core/Completeness/TermStructureCases.v +++ b/theories/Core/Completeness/TermStructureCases.v @@ -1,5 +1,6 @@ From Coq Require Import Morphisms_Relations RelationClasses. -From Mcltt Require Import Base LibTactics LogicalRelation System. +From Mcltt Require Import Base LibTactics. +From Mcltt.Core Require Import Completeness.LogicalRelation System. Import Domain_Notations. Lemma rel_exp_sub_cong : forall {Δ M M' A σ σ' Γ}, @@ -13,21 +14,19 @@ Proof. destruct_conjs. pose (env_relΔ0 := env_relΔ). handle_per_ctx_env_irrel. - eexists. - eexists; try eassumption. - eexists. + eexists_rel_exp. intros. - assert (env_relΓ p' p) by (symmetry; eauto). - assert (env_relΓ p p) by (etransitivity; eauto). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + assert (env_relΓ p' p) by (symmetry; eassumption). + assert (env_relΓ p p) by (etransitivity; eassumption). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). handle_per_univ_elem_irrel. - assert (env_relΔ o o0) by (etransitivity; [|symmetry; intuition]; intuition). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΔ H). + assert (env_relΔ o o0) by (etransitivity; [|symmetry; eassumption]; eassumption). + (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_exp. destruct_by_head rel_typ. handle_per_univ_elem_irrel. eexists. - split; [> econstructor; only 1-2: econstructor; eauto ..]. + split; [> econstructor; only 1-2: econstructor; eassumption ..]. Qed. Lemma rel_exp_sub_id : forall {Γ M A}, @@ -36,16 +35,14 @@ Lemma rel_exp_sub_id : forall {Γ M A}, Proof. intros * [env_relΓ]. destruct_conjs. - eexists. - eexists; try eassumption. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_exp. destruct_by_head rel_typ. eexists. - split; econstructor; eauto. - repeat econstructor; mauto. + split; econstructor; try eassumption. + repeat econstructor; eassumption. Qed. Lemma rel_exp_sub_compose : forall {Γ τ Γ' σ Γ'' M A}, @@ -61,23 +58,21 @@ Proof. pose (env_relΓ'0 := env_relΓ'). pose (env_relΓ''0 := env_relΓ''). handle_per_ctx_env_irrel. - eexists. - eexists; try eassumption. - eexists. + eexists_rel_exp. intros. assert (env_relΓ p' p) by (eapply per_env_sym; eauto). assert (env_relΓ p p) by (eapply per_env_trans; eauto). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). handle_per_univ_elem_irrel. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ' H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ'). handle_per_univ_elem_irrel. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ'' H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ''). handle_per_univ_elem_irrel. destruct_by_head rel_exp. destruct_by_head rel_typ. handle_per_univ_elem_irrel. eexists. - split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. + split; [> econstructor; only 1-2: repeat econstructor; eassumption ..]. Qed. Lemma rel_exp_conv : forall {Γ M M' A A' i}, @@ -91,12 +86,10 @@ Proof. destruct_conjs. pose (env_relΓ0 := env_relΓ). handle_per_ctx_env_irrel. - eexists. - eexists; try eassumption. - eexists. + eexists_rel_exp. intros. assert (env_relΓ p p) by (eapply per_env_trans; eauto; eapply per_env_sym; eauto). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_exp. destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ Type@i }}}); subst. @@ -110,8 +103,8 @@ Proof. destruct_conjs. handle_per_univ_elem_irrel. eexists. - split; econstructor; eauto. - etransitivity; [symmetry |]; eauto. + split; econstructor; try eassumption. + etransitivity; [symmetry |]; eassumption. Qed. Lemma rel_exp_sym : forall {Γ M M' A}, @@ -122,18 +115,16 @@ Proof. pose proof (@relation_equivalence_pointwise env). intros * [env_relΓ]. destruct_conjs. - econstructor. - eexists; try eassumption. - eexists. - intros ? ? equiv_p_p'. + eexists_rel_exp. + intros. assert (env_relΓ p' p) by (eapply per_env_sym; eauto). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H); destruct_conjs. + (on_all_hyp: destruct_rel_by_assumption env_relΓ); destruct_conjs. destruct_by_head rel_exp. destruct_by_head rel_typ. handle_per_univ_elem_irrel. eexists. - split; econstructor; eauto. - eapply per_elem_sym; eauto. + split; econstructor; try eassumption. + symmetry; eassumption. Qed. Lemma rel_exp_trans : forall {Γ M1 M2 M3 A}, @@ -147,19 +138,17 @@ Proof. destruct_conjs. pose (env_relΓ0 := env_relΓ). handle_per_ctx_env_irrel. - econstructor. - eexists; try eassumption. - eexists. - intros ? ? equiv_p_p'. + eexists_rel_exp. + intros. assert (env_relΓ p' p) by (symmetry; eauto). assert (env_relΓ p' p') by (etransitivity; eauto). - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H); destruct_conjs. + (on_all_hyp: destruct_rel_by_assumption env_relΓ); destruct_conjs. destruct_by_head rel_exp. destruct_by_head rel_typ. handle_per_univ_elem_irrel. eexists. - split; econstructor; eauto. - etransitivity; eauto. + split; econstructor; try eassumption. + etransitivity; eassumption. Qed. #[export] @@ -183,22 +172,19 @@ Proof. try solve [intuition]; clear Hpart; destruct Hrel as [env_relΓ]; destruct_conjs. - - eexists; eauto. + - eexists; eassumption. - destruct_by_head valid_exp_under_ctx. destruct_conjs. eexists. - eexists. - eexists; [eassumption |]. - eexists. + eexists_rel_exp. intros. - (on_all_hyp: fun H => destruct_rel_by_assumption env_relΓ H). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). evar (j : nat). eexists (per_univ j). subst j. split. - + econstructor; only 1-2: repeat econstructor; eauto. + + econstructor; only 1-2: repeat econstructor; try eassumption. per_univ_elem_econstructor; eauto. - unfold per_univ. - reflexivity. + apply Equivalence_Reflexive. + eapply rel_typ_implies_rel_exp; eassumption. Qed. diff --git a/theories/Core/Completeness/UniverseCases.v b/theories/Core/Completeness/UniverseCases.v index 6b55077c..62c8b4ec 100644 --- a/theories/Core/Completeness/UniverseCases.v +++ b/theories/Core/Completeness/UniverseCases.v @@ -1,5 +1,6 @@ -From Coq Require Import Morphisms_Relations. -From Mcltt Require Import Base LibTactics LogicalRelation. +From Coq Require Import Morphisms_Relations RelationClasses. +From Mcltt Require Import Base LibTactics. +From Mcltt.Core Require Import Completeness.LogicalRelation. Import Domain_Notations. Lemma valid_typ : forall {i Γ}, @@ -7,13 +8,11 @@ Lemma valid_typ : forall {i Γ}, {{ Γ ⊨ Type@i : Type@(S i) }}. Proof. intros * []. - econstructor. - eexists; try eassumption. - eexists. + eexists_rel_exp. intros. - exists (per_univ (S i)). - split; [> econstructor; only 1-2: econstructor; eauto ..]; [| exists (per_univ i)]; - per_univ_elem_econstructor; mauto; reflexivity. + eexists (per_univ _). + split; [> econstructor; only 1-2: econstructor; eauto ..]; [| eexists (per_univ _)]; + per_univ_elem_econstructor; eauto; apply Equivalence_Reflexive. Qed. Lemma rel_exp_typ_sub : forall {i Γ σ Δ}, @@ -22,14 +21,12 @@ Lemma rel_exp_typ_sub : forall {i Γ σ Δ}, Proof. intros * [env_rel]. destruct_conjs. - econstructor. - eexists; try eassumption. - eexists. + eexists_rel_exp. intros. - exists (per_univ (S i)). - (on_all_hyp: fun H => destruct_rel_by_assumption env_rel H). - split; [> econstructor; only 1-2: repeat econstructor; eauto ..]; [| exists (per_univ i)]; - per_univ_elem_econstructor; mauto; reflexivity. + eexists (per_univ _). + (on_all_hyp: destruct_rel_by_assumption env_rel). + split; [> econstructor; only 1-2: repeat econstructor; eauto ..]; [| eexists (per_univ _)]; + per_univ_elem_econstructor; eauto; apply Equivalence_Reflexive. Qed. Lemma rel_exp_cumu : forall {i Γ A A'}, @@ -40,20 +37,18 @@ Proof. pose proof (@relation_equivalence_pointwise env). intros * [env_rel]. destruct_conjs. - econstructor. - eexists; try eassumption. - exists (S (S i)). + eexists_rel_exp. intros. - exists (per_univ (S i)). - (on_all_hyp: fun H => destruct_rel_by_assumption env_rel H). + eexists (per_univ _). + (on_all_hyp: destruct_rel_by_assumption env_rel). inversion_by_head rel_typ. inversion_by_head rel_exp. inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match_by_head per_univ_elem ltac:(fun H => invert_per_univ_elem H); subst. + match_by_head per_univ_elem invert_per_univ_elem; subst. handle_per_univ_elem_irrel. destruct_conjs. match_by_head per_univ_elem ltac:(fun H => apply per_univ_elem_cumu in H). split; [> econstructor; only 1-2: repeat econstructor; eauto ..]; [| eexists; eauto]. - per_univ_elem_econstructor; mauto. + per_univ_elem_econstructor; eauto. reflexivity. Qed. diff --git a/theories/Core/Completeness/VariableCases.v b/theories/Core/Completeness/VariableCases.v index 3d3d04e8..c47beb3c 100644 --- a/theories/Core/Completeness/VariableCases.v +++ b/theories/Core/Completeness/VariableCases.v @@ -1,5 +1,6 @@ -From Coq Require Import Morphisms_Relations Relations. -From Mcltt Require Import Base LibTactics LogicalRelation System. +From Coq Require Import Morphisms_Relations RelationClasses. +From Mcltt Require Import Base LibTactics. +From Mcltt.Core Require Import Completeness.LogicalRelation System. Import Domain_Notations. Lemma valid_lookup : forall {Γ x A env_rel} @@ -21,7 +22,7 @@ Proof with solve [repeat econstructor; mauto]. [|specialize (IHHxinΓ _ _ _ equiv_Γ_Γ' H2) as [j ?]; destruct_conjs]; apply_relation_equivalence; eexists; intros ? ? []; - (on_all_hyp: fun H => destruct_rel_by_assumption tail_rel H); destruct_conjs; + (on_all_hyp: destruct_rel_by_assumption tail_rel); destruct_conjs; eexists. - split; econstructor... - destruct_by_head rel_typ. @@ -36,8 +37,57 @@ Lemma valid_var : forall {Γ x A}, {{ Γ ⊨ #x : A }}. Proof. intros * [? equiv_Γ_Γ] ?. - econstructor. - unshelve epose proof (valid_lookup equiv_Γ_Γ _); mauto. + unshelve epose proof (valid_lookup equiv_Γ_Γ _) as []; try eassumption. + eexists_rel_exp; eassumption. +Qed. + +Lemma rel_exp_var_0_sub : forall {Γ M σ Δ A}, + {{ Γ ⊨s σ : Δ }} -> + {{ Γ ⊨ M : A[σ] }} -> + {{ Γ ⊨ #0[σ ,, M] ≈ M : A[σ] }}. +Proof. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ [? [env_relΔ]]] []. + destruct_conjs. + pose (env_relΓ0 := env_relΓ). + handle_per_ctx_env_irrel. + eexists_rel_exp. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + destruct_by_head rel_typ. + destruct_by_head rel_exp. + inversion_by_head (eval_exp {{{ A[σ] }}}); subst. + functional_eval_rewrite_clear. + eexists. + split; [> econstructor; only 1-2: repeat econstructor ..]; eassumption. +Qed. + +Lemma rel_exp_var_S_sub : forall {Γ M σ Δ A x B}, + {{ Γ ⊨s σ : Δ }} -> + {{ Γ ⊨ M : A[σ] }} -> + {{ #x : B ∈ Δ }} -> + {{ Γ ⊨ #(S x)[σ ,, M] ≈ #x[σ] : B[σ] }}. +Proof. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ [? [env_relΔ]]] [] HxinΓ. + destruct_conjs. + pose (env_relΓ0 := env_relΓ). + handle_per_ctx_env_irrel. + unshelve epose proof (valid_lookup _ HxinΓ); revgoals; try eassumption. + destruct_conjs. + eexists_rel_exp. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + (on_all_hyp: destruct_rel_by_assumption env_relΔ). + destruct_by_head rel_typ. + destruct_by_head rel_exp. + inversion_by_head (eval_exp {{{ A[σ] }}}); subst. + inversion_by_head (eval_exp {{{ # x }}}); subst. + functional_eval_rewrite_clear. + eexists. + split; [> econstructor; only 1-2: repeat econstructor ..]; eassumption. Qed. Lemma rel_exp_var_weaken : forall {Γ B x A}, @@ -47,19 +97,17 @@ Lemma rel_exp_var_weaken : forall {Γ B x A}, Proof. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [] HxinΓ. - match_by_head1 per_ctx_env ltac:(fun H => inversion H); subst. - unshelve epose proof (valid_lookup _ HxinΓ); revgoals; mauto. + intros * [env_relΓB] HxinΓ. + inversion_by_head (per_ctx_env env_relΓB); subst. + unshelve epose proof (valid_lookup _ HxinΓ); revgoals; try eassumption. destruct_conjs. - eexists. - eexists; try eassumption. - eexists. + eexists_rel_exp. apply_relation_equivalence. intros ? ? []. - (on_all_hyp: fun H => destruct_rel_by_assumption tail_rel H). + (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. destruct_by_head rel_exp. inversion_by_head (eval_exp {{{ #x }}}); subst. eexists. - split; [> econstructor; only 1-2: repeat econstructor; mauto ..]. + split; [> econstructor; only 1-2: repeat econstructor ..]; eassumption. Qed. diff --git a/theories/_CoqProject b/theories/_CoqProject index 85235f52..a13a6832 100644 --- a/theories/_CoqProject +++ b/theories/_CoqProject @@ -4,10 +4,11 @@ ./Core/Axioms.v ./Core/Base.v +./Core/Completeness/FunctionCases.v ./Core/Completeness/LogicalRelation/Definitions.v ./Core/Completeness/LogicalRelation/Lemmas.v +./Core/Completeness/LogicalRelation/Tactics.v ./Core/Completeness/LogicalRelation.v -./Core/Completeness/FunctionCases.v ./Core/Completeness/TermStructureCases.v ./Core/Completeness/UniverseCases.v ./Core/Completeness/VariableCases.v From 12f0cb063114679313fd1f8fdfb2bccdb5db2a82 Mon Sep 17 00:00:00 2001 From: "Junyoung/\"Clare\" Jang" <jjc9310@gmail.com> Date: Tue, 21 May 2024 16:25:18 -0400 Subject: [PATCH 2/8] Fix a tactic --- theories/Core/Semantic/PER/Lemmas.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theories/Core/Semantic/PER/Lemmas.v b/theories/Core/Semantic/PER/Lemmas.v index 5fcbb9ef..351a2e3c 100644 --- a/theories/Core/Semantic/PER/Lemmas.v +++ b/theories/Core/Semantic/PER/Lemmas.v @@ -220,7 +220,7 @@ Ltac rewrite_relation_equivalence_left := Ltac rewrite_relation_equivalence_right := repeat match goal with | H : ?R1 <~> ?R2 |- _ => - try setoid_rewrite H; + try setoid_rewrite <- H; (on_all_hyp: fun H' => assert_fails (unify H H'); unmark H; setoid_rewrite <- H in H'); let T := type of H in fold (id T) in H From 588d8293996cb30dbf54f0050a45a296ca623f84 Mon Sep 17 00:00:00 2001 From: Junyoung/Clare Jang <jjc9310@gmail.com> Date: Tue, 21 May 2024 04:22:37 -0400 Subject: [PATCH 3/8] Finish context and subst --- theories/Core/Completeness/ContextCases.v | 48 ++++ .../Core/Completeness/SubstitutionCases.v | 238 ++++++++++++++++++ theories/_CoqProject | 2 + 3 files changed, 288 insertions(+) create mode 100644 theories/Core/Completeness/ContextCases.v create mode 100644 theories/Core/Completeness/SubstitutionCases.v diff --git a/theories/Core/Completeness/ContextCases.v b/theories/Core/Completeness/ContextCases.v new file mode 100644 index 00000000..2129ea1f --- /dev/null +++ b/theories/Core/Completeness/ContextCases.v @@ -0,0 +1,48 @@ +From Coq Require Import Morphisms_Relations RelationClasses. +From Mcltt Require Import Base LibTactics. +From Mcltt.Core Require Import Completeness.LogicalRelation System. +Import Domain_Notations. + +Proposition valid_ctx_empty : + {{ ⊨ ⋅ }}. +Proof. + do 2 econstructor. + apply Equivalence_Reflexive. +Qed. + +Lemma rel_ctx_extend : forall {Γ Γ' A A' i}, + {{ ⊨ Γ ≈ Γ' }} -> + {{ Γ ⊨ A ≈ A' : Type@i }} -> + {{ ⊨ Γ, A ≈ Γ', A' }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓΓ'] [env_relΓ]. + pose (env_relΓ0 := env_relΓ). + destruct_conjs. + handle_per_ctx_env_irrel. + eexists. + econstructor; eauto with typeclass_instances. + - instantiate (1 := fun p p' (equiv_p_p' : env_relΓ p p') m m' => + forall i a a' R, + {{ ⟦ A ⟧ p ↘ a }} -> + {{ ⟦ A' ⟧ p' ↘ a' }} -> + per_univ_elem i R a a' -> + R m m'). + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ Type@i }}}); subst. + match goal with + | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => + invert_per_univ_elem H; + apply_relation_equivalence; + clear_refl_eqs + end. + destruct_by_head rel_exp. + destruct_conjs. + econstructor; eauto. + apply -> per_univ_elem_morphism_iff; eauto. + split; intros; handle_per_univ_elem_irrel... + - apply Equivalence_Reflexive. +Qed. diff --git a/theories/Core/Completeness/SubstitutionCases.v b/theories/Core/Completeness/SubstitutionCases.v new file mode 100644 index 00000000..c38d3952 --- /dev/null +++ b/theories/Core/Completeness/SubstitutionCases.v @@ -0,0 +1,238 @@ +From Coq Require Import Morphisms_Relations RelationClasses. +From Mcltt Require Import Base LibTactics. +From Mcltt.Core Require Import Completeness.ContextCases Completeness.LogicalRelation System. +Import Domain_Notations. + +Lemma rel_subst_id : forall {Γ}, + {{ ⊨ Γ }} -> + {{ Γ ⊨s Id ≈ Id : Γ }}. +Proof with intuition. + intros * []. + eexists_rel_subst. + econstructor; only 1-2: repeat econstructor... +Qed. + +Lemma rel_subst_weaken : forall {Γ A}, + {{ ⊨ Γ, A }} -> + {{ Γ, A ⊨s Wk ≈ Wk : Γ }}. +Proof with intuition. + intros * [env_relΓA]. + inversion_by_head (per_ctx_env env_relΓA); subst. + eexists_rel_subst. + econstructor; only 1-2: repeat econstructor... +Qed. + +Lemma rel_subst_compose_cong : forall {Γ τ τ' Γ' σ σ' Γ''}, + {{ Γ ⊨s τ ≈ τ' : Γ' }} -> + {{ Γ' ⊨s σ ≈ σ' : Γ'' }} -> + {{ Γ ⊨s σ ∘ τ ≈ σ' ∘ τ' : Γ'' }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ [? [env_relΓ']]] []. + destruct_conjs. + pose (env_relΓ'0 := env_relΓ'). + handle_per_ctx_env_irrel. + eexists_rel_subst. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + (on_all_hyp: destruct_rel_by_assumption env_relΓ'). + econstructor; only 1-2: repeat econstructor... +Qed. + +Lemma rel_subst_extend_cong : forall {i Γ M M' σ σ' Δ A}, + {{ Γ ⊨s σ ≈ σ' : Δ }} -> + {{ Δ ⊨ A : Type@i }} -> + {{ Γ ⊨ M ≈ M' : A[σ] }} -> + {{ Γ ⊨s σ ,, M ≈ σ' ,, M' : Δ, A }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ [? [env_relΔ]]] HA []. + destruct_conjs. + pose (env_relΓ0 := env_relΓ). + pose (env_relΔ0 := env_relΔ). + assert {{ ⊨ Δ, A }} as [env_relΔA] by (eapply rel_ctx_extend; eauto; eexists; eassumption). + destruct_conjs. + pose (env_relΔA0 := env_relΔA). + handle_per_ctx_env_irrel. + eexists_rel_subst. + inversion_by_head (per_ctx_env env_relΔA); subst. + handle_per_ctx_env_irrel. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + (on_all_hyp: destruct_rel_by_assumption tail_rel). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ A[σ] }}}); subst. + handle_per_univ_elem_irrel. + destruct_by_head rel_exp. + econstructor; only 1-2: repeat econstructor; eauto. +Qed. + +Lemma rel_subst_id_compose_right : forall {Γ σ Δ}, + {{ Γ ⊨s σ : Δ }} -> + {{ Γ ⊨s Id ∘ σ ≈ σ : Δ }}. +Proof with intuition. + intros * [env_relΓ]. + destruct_conjs. + eexists_rel_subst. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + econstructor; only 1-2: repeat econstructor... +Qed. + +Lemma rel_subst_id_compose_left : forall {Γ σ Δ}, + {{ Γ ⊨s σ : Δ }} -> + {{ Γ ⊨s σ ∘ Id ≈ σ : Δ }}. +Proof with intuition. + intros * [env_relΓ]. + destruct_conjs. + eexists_rel_subst. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + econstructor; only 1-2: repeat econstructor... +Qed. + +Lemma rel_subst_compose_assoc : forall {Γ σ Γ' σ' Γ'' σ'' Γ'''}, + {{ Γ' ⊨s σ : Γ }} -> + {{ Γ'' ⊨s σ' : Γ' }} -> + {{ Γ''' ⊨s σ'' : Γ'' }} -> + {{ Γ''' ⊨s (σ ∘ σ') ∘ σ'' ≈ σ ∘ (σ' ∘ σ'') : Γ }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ' [? [env_relΓ]]] [env_relΓ'' [? []]] [env_relΓ''']. + destruct_conjs. + pose (env_relΓ'0 := env_relΓ'). + pose (env_relΓ''0 := env_relΓ''). + handle_per_ctx_env_irrel. + eexists_rel_subst. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ'''). + (on_all_hyp: destruct_rel_by_assumption env_relΓ''). + (on_all_hyp: destruct_rel_by_assumption env_relΓ'). + econstructor; only 1-2: repeat econstructor... +Qed. + +Lemma rel_subst_extend_compose : forall {Γ τ Γ' M σ Γ'' A i}, + {{ Γ' ⊨s σ : Γ'' }} -> + {{ Γ'' ⊨ A : Type@i }} -> + {{ Γ' ⊨ M : A[σ] }} -> + {{ Γ ⊨s τ : Γ' }} -> + {{ Γ ⊨s (σ ,, M) ∘ τ ≈ (σ ∘ τ) ,, M[τ] : Γ'', A }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ' [? [env_relΓ'']]] HA [] [env_relΓ]. + destruct_conjs. + pose (env_relΓ'0 := env_relΓ'). + pose (env_relΓ''0 := env_relΓ''). + assert {{ ⊨ Γ'', A }} as [env_relΓ''A] by (eapply rel_ctx_extend; eauto; eexists; eassumption). + destruct_conjs. + pose (env_relΓ''A0 := env_relΓ''A). + handle_per_ctx_env_irrel. + eexists_rel_subst. + inversion_by_head (per_ctx_env env_relΓ''A); subst. + handle_per_ctx_env_irrel. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + (on_all_hyp: destruct_rel_by_assumption env_relΓ'). + (on_all_hyp: destruct_rel_by_assumption tail_rel). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ A[σ] }}}); subst. + handle_per_univ_elem_irrel. + destruct_by_head rel_exp. + econstructor; only 1-2: repeat econstructor; try eexists... +Qed. + +Lemma rel_subst_p_extend : forall {Γ' M σ Γ A}, + {{ Γ' ⊨s σ : Γ }} -> + {{ Γ' ⊨ M : A[σ] }} -> + {{ Γ' ⊨s Wk ∘ (σ ,, M) ≈ σ : Γ }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ' [? [env_relΓ]]] []. + destruct_conjs. + pose (env_relΓ0 := env_relΓ). + pose (env_relΓ'0 := env_relΓ'). + handle_per_ctx_env_irrel. + eexists_rel_subst. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ'). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ A[σ] }}}); subst. + handle_per_univ_elem_irrel. + destruct_by_head rel_exp. + econstructor; only 1-2: repeat econstructor... +Qed. + +Lemma rel_subst_extend : forall {Γ' σ Γ A}, + {{ Γ' ⊨s σ : Γ, A }} -> + {{ Γ' ⊨s σ ≈ (Wk ∘ σ) ,, #0[σ] : Γ, A }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ' [? [env_relΓA]]]. + destruct_conjs. + pose (env_relΓA0 := env_relΓA). + pose (env_relΓ'0 := env_relΓ'). + inversion_by_head (per_ctx_env env_relΓA); subst. + rename tail_rel into env_relΓ. + handle_per_ctx_env_irrel. + eexists_rel_subst. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ'). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + econstructor; only 1-2: repeat econstructor; try eexists... +Qed. + +Lemma rel_subst_sym : forall {Γ σ σ' Δ}, + {{ Γ ⊨s σ ≈ σ' : Δ }} -> + {{ Γ ⊨s σ' ≈ σ : Δ }}. +Proof with intuition. + intros * [env_relΓ]. + destruct_conjs. + eexists_rel_subst. + intros. + assert (env_relΓ p' p) by (symmetry; eassumption). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + econstructor; only 1-2: repeat econstructor; try symmetry... +Qed. + +Lemma rel_subst_trans : forall {Γ σ σ' σ'' Δ}, + {{ Γ ⊨s σ ≈ σ' : Δ }} -> + {{ Γ ⊨s σ' ≈ σ'' : Δ }} -> + {{ Γ ⊨s σ ≈ σ'' : Δ }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ] []. + destruct_conjs. + pose (env_relΓ0 := env_relΓ). + handle_per_ctx_env_irrel. + eexists_rel_subst. + intros. + assert (env_relΓ p' p') by (etransitivity; [symmetry |]; eassumption). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + functional_eval_rewrite_clear. + econstructor; only 1-2: repeat econstructor; try etransitivity... +Qed. + +Lemma rel_subst_conv : forall {Γ σ σ' Δ Δ'}, + {{ Γ ⊨s σ ≈ σ' : Δ }} -> + {{ ⊨ Δ ≈ Δ' }} -> + {{ Γ ⊨s σ ≈ σ' : Δ' }}. +Proof with intuition. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓ [? [env_relΔ]]] []. + destruct_conjs. + pose (env_relΔ0 := env_relΔ). + handle_per_ctx_env_irrel. + assert {{ EF Δ' ≈ Δ' ∈ per_ctx_env ↘ env_relΔ }} by (etransitivity; [symmetry |]; eassumption). + eexists_rel_subst. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + econstructor; only 1-2: repeat econstructor... +Qed. diff --git a/theories/_CoqProject b/theories/_CoqProject index a13a6832..f4b23c16 100644 --- a/theories/_CoqProject +++ b/theories/_CoqProject @@ -4,11 +4,13 @@ ./Core/Axioms.v ./Core/Base.v +./Core/Completeness/ContextCases.v ./Core/Completeness/FunctionCases.v ./Core/Completeness/LogicalRelation/Definitions.v ./Core/Completeness/LogicalRelation/Lemmas.v ./Core/Completeness/LogicalRelation/Tactics.v ./Core/Completeness/LogicalRelation.v +./Core/Completeness/SubstitutionCases.v ./Core/Completeness/TermStructureCases.v ./Core/Completeness/UniverseCases.v ./Core/Completeness/VariableCases.v From 268068e5bd5cd940706152067acc5a72f4cdb13d Mon Sep 17 00:00:00 2001 From: Junyoung/Clare Jang <jjc9310@gmail.com> Date: Tue, 21 May 2024 04:22:47 -0400 Subject: [PATCH 4/8] Add some cases for nat --- theories/Core/Completeness/NatCases.v | 108 ++++++++++++++++++++++++++ theories/_CoqProject | 1 + 2 files changed, 109 insertions(+) create mode 100644 theories/Core/Completeness/NatCases.v diff --git a/theories/Core/Completeness/NatCases.v b/theories/Core/Completeness/NatCases.v new file mode 100644 index 00000000..fc12a768 --- /dev/null +++ b/theories/Core/Completeness/NatCases.v @@ -0,0 +1,108 @@ +From Coq Require Import Morphisms_Relations RelationClasses. +From Mcltt Require Import Base LibTactics. +From Mcltt.Core Require Import Completeness.LogicalRelation System. +Import Domain_Notations. + +Lemma valid_exp_nat : forall {Γ i}, + {{ ⊨ Γ }} -> + {{ Γ ⊨ ℕ : Type@i }}. +Proof. + intros * [env_relΓ]. + eexists_rel_exp. + intros. + eexists (per_univ _). + split; [> econstructor; only 1-2: repeat econstructor ..]; [| eexists]; + per_univ_elem_econstructor; eauto; apply Equivalence_Reflexive. +Qed. + +Lemma rel_exp_nat_sub : forall {Γ σ i Δ}, + {{ Γ ⊨s σ : Δ }} -> + {{ Γ ⊨ ℕ[σ] ≈ ℕ : Type@i }}. +Proof. + intros * [env_relΓ]. + destruct_conjs. + eexists_rel_exp. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + eexists (per_univ _). + split; [> econstructor; only 1-2: repeat econstructor ..]; eauto; [| eexists]; + per_univ_elem_econstructor; eauto; apply Equivalence_Reflexive. +Qed. + +Lemma valid_exp_zero : forall {Γ}, + {{ ⊨ Γ }} -> + {{ Γ ⊨ zero : ℕ }}. +Proof. + intros * [env_relΓ]. + unshelve eexists_rel_exp; [constructor |]. + intros. + eexists. + split; [> econstructor; only 1-2: repeat econstructor ..]. + - per_univ_elem_econstructor; reflexivity. + - econstructor. +Qed. + +Lemma rel_exp_zero_sub : forall {Γ σ Δ}, + {{ Γ ⊨s σ : Δ }} -> + {{ Γ ⊨ zero[σ] ≈ zero : ℕ }}. +Proof. + intros * [env_relΓ]. + destruct_conjs. + unshelve eexists_rel_exp; [constructor |]. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + eexists. + split; [> econstructor; only 1-2: repeat econstructor ..]; eauto. + - per_univ_elem_econstructor; reflexivity. + - econstructor. +Qed. + +Lemma rel_exp_succ_sub : forall {Γ σ Δ M}, + {{ Γ ⊨s σ : Δ }} -> + {{ Δ ⊨ M : ℕ }} -> + {{ Γ ⊨ (succ M)[σ] ≈ succ (M[σ]) : ℕ }}. +Proof. + intros * [env_relΓ] [env_relΔ]. + destruct_conjs. + pose (env_relΔ0 := env_relΔ). + handle_per_ctx_env_irrel. + unshelve eexists_rel_exp; [constructor |]. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + (on_all_hyp: destruct_rel_by_assumption env_relΔ). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ ℕ }}}); subst. + match goal with + | H : per_univ_elem _ _ d{{{ ℕ }}} d{{{ ℕ }}} |- _ => + invert_per_univ_elem H; + apply_relation_equivalence + end. + destruct_by_head rel_exp. + eexists. + split; [> econstructor; only 1-2: repeat econstructor ..]; eauto. + - per_univ_elem_econstructor; reflexivity. + - econstructor; eassumption. +Qed. + +Lemma rel_exp_succ_cong : forall {Γ M M'}, + {{ Γ ⊨ M ≈ M' : ℕ }} -> + {{ Γ ⊨ succ M ≈ succ M' : ℕ }}. +Proof. + intros * [env_relΓ]. + destruct_conjs. + unshelve eexists_rel_exp; [constructor |]. + intros. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ ℕ }}}); subst. + match goal with + | H : per_univ_elem _ _ d{{{ ℕ }}} d{{{ ℕ }}} |- _ => + invert_per_univ_elem H; + apply_relation_equivalence + end. + destruct_by_head rel_exp. + eexists. + split; [> econstructor; only 1-2: repeat econstructor ..]; eauto. + - per_univ_elem_econstructor; reflexivity. + - econstructor; eassumption. +Qed. diff --git a/theories/_CoqProject b/theories/_CoqProject index f4b23c16..d5e5a6d9 100644 --- a/theories/_CoqProject +++ b/theories/_CoqProject @@ -10,6 +10,7 @@ ./Core/Completeness/LogicalRelation/Lemmas.v ./Core/Completeness/LogicalRelation/Tactics.v ./Core/Completeness/LogicalRelation.v +./Core/Completeness/NatCases.v ./Core/Completeness/SubstitutionCases.v ./Core/Completeness/TermStructureCases.v ./Core/Completeness/UniverseCases.v From 2093d66c9075dbbe4e601080fc744a9b773bcd07 Mon Sep 17 00:00:00 2001 From: "Junyoung/\"Clare\" Jang" <jjc9310@gmail.com> Date: Tue, 21 May 2024 14:59:00 -0400 Subject: [PATCH 5/8] Improve completeness proofs --- theories/Core/Completeness/ContextCases.v | 8 +- theories/Core/Completeness/FunctionCases.v | 96 ++++++------------- .../Completeness/LogicalRelation/Tactics.v | 12 +++ theories/Core/Completeness/NatCases.v | 14 +-- .../Core/Completeness/TermStructureCases.v | 13 +-- theories/Core/Completeness/UniverseCases.v | 3 +- theories/Core/Completeness/VariableCases.v | 9 +- theories/LibTactics.v | 16 +++- 8 files changed, 64 insertions(+), 107 deletions(-) diff --git a/theories/Core/Completeness/ContextCases.v b/theories/Core/Completeness/ContextCases.v index 2129ea1f..4221c87c 100644 --- a/theories/Core/Completeness/ContextCases.v +++ b/theories/Core/Completeness/ContextCases.v @@ -32,13 +32,7 @@ Proof with intuition. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence; - clear_refl_eqs - end. + invert_rel_typ_body. destruct_by_head rel_exp. destruct_conjs. econstructor; eauto. diff --git a/theories/Core/Completeness/FunctionCases.v b/theories/Core/Completeness/FunctionCases.v index 7e142ee5..e43f20bb 100644 --- a/theories/Core/Completeness/FunctionCases.v +++ b/theories/Core/Completeness/FunctionCases.v @@ -31,7 +31,7 @@ Proof with intuition. pose proof (@relation_equivalence_pointwise env). intros. subst. - (on_all_hyp: fun H => pose proof (H _ _ equiv_c_c')). + (on_all_hyp: destruct_rel_by_assumption (head_rel p p' equiv_p_p')). destruct_by_head rel_exp. econstructor; mauto. destruct_by_head per_univ. @@ -56,17 +56,11 @@ Proof with intuition. intros. (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence; - clear_refl_eqs - end. + invert_rel_typ_body. destruct_by_head rel_exp. destruct_conjs. handle_per_univ_elem_irrel. - exists (per_univ i). + eexists (per_univ _). split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. eexists. per_univ_elem_econstructor; eauto with typeclass_instances. @@ -76,16 +70,10 @@ Proof with intuition. clear dependent c'. intros. extract_output_info_with p c p' c' env_relΓA. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence; - clear_refl_eqs - end. + invert_rel_typ_body. econstructor... + reflexivity. - - (* `reflexivity` does not work as it uses a "wrong" instance. *) + - (* `reflexivity` does not work as (simple) unification fails for some unknown reason. *) apply Equivalence_Reflexive. Qed. @@ -108,18 +96,12 @@ Proof with intuition. assert {{ Dom o' ≈ o' ∈ tail_rel }} by (etransitivity; [symmetry|]; eassumption). (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence; - clear_refl_eqs - end. + invert_rel_typ_body. destruct_by_head rel_exp. destruct_conjs. handle_per_univ_elem_irrel. - eexists; split; - [> econstructor; only 1-2: repeat econstructor; eauto ..]. + eexists. + split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. eexists. per_univ_elem_econstructor; eauto with typeclass_instances. - intros. @@ -128,17 +110,12 @@ Proof with intuition. clear dependent c'. intros. extract_output_info_with o c o' c' env_relΔA. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence; - clear_refl_eqs - end. + invert_rel_typ_body. + destruct_conjs. econstructor; eauto. repeat econstructor... + reflexivity. - - (* `reflexivity` does not work as it uses a "wrong" instance. *) + - (* `reflexivity` does not work as (simple) unification fails for some unknown reason. *) apply Equivalence_Reflexive. Qed. @@ -159,18 +136,13 @@ Proof with intuition. intros. (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence; - clear_refl_eqs - end. + invert_rel_typ_body. destruct_by_head rel_exp. functional_eval_rewrite_clear. - eexists ?[elem_rel]. + eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. - - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; eauto with typeclass_instances. + - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; + eauto with typeclass_instances. + intros. eapply rel_exp_pi_core; eauto. * clear dependent c. @@ -207,9 +179,10 @@ Proof with intuition. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). (on_all_hyp: destruct_rel_by_assumption tail_rel). - eexists ?[elem_rel]. + eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. - - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; eauto with typeclass_instances. + - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; + eauto with typeclass_instances. + intros. eapply rel_exp_pi_core; eauto. * clear dependent c. @@ -245,22 +218,22 @@ Proof with intuition. assert (equiv_p'_p' : env_relΓ p' p') by (etransitivity; [symmetry |]; eauto). (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Π A B }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ Π ~?a ~?p B }}} d{{{ Π ~?a' ~?p' B }}} |- _ => - invert_per_univ_elem H - end. + functional_eval_rewrite_clear. + invert_rel_typ_body. handle_per_univ_elem_irrel. destruct_by_head rel_exp. functional_eval_rewrite_clear. - assert (in_rel m1 m2) by (etransitivity; [| symmetry]; eauto). + assert (in_rel0 m1 m2) by (etransitivity; [| symmetry]; eauto). + assert (in_rel m1 m'2) by intuition. + assert (in_rel m1 m2) by intuition. (on_all_hyp: destruct_rel_by_assumption in_rel). - (on_all_hyp_rev: destruct_rel_by_assumption in_rel). + (on_all_hyp: destruct_rel_by_assumption in_rel0). + (on_all_hyp_rev: destruct_rel_by_assumption in_rel0). handle_per_univ_elem_irrel. - eexists ?[elem_rel]. + eexists. split; [> econstructor; only 1-2: econstructor ..]. 1,3: repeat econstructor. - all: eauto. + all: intuition. Qed. Lemma rel_exp_app_sub : forall {Γ σ Δ M A B N}, @@ -281,16 +254,12 @@ Proof with intuition. (on_all_hyp: destruct_rel_by_assumption env_relΓ). (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Π A B }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ Π ~?a ~?p B }}} d{{{ Π ~?a' ~?p' B }}} |- _ => - invert_per_univ_elem H - end. + invert_rel_typ_body. handle_per_univ_elem_irrel. destruct_by_head rel_exp. functional_eval_rewrite_clear. (on_all_hyp_rev: destruct_rel_by_assumption in_rel). - eexists ?[elem_rel]. + eexists. split; [> econstructor; only 1-2: econstructor ..]. 1,3,8,9: repeat econstructor. 15: econstructor. @@ -335,12 +304,7 @@ Proof with intuition. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Π A B }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ Π ~?a ~?p B }}} d{{{ Π ~?a' ~?p' B }}} |- _ => - invert_per_univ_elem H - end. - apply_relation_equivalence. + invert_rel_typ_body. destruct_by_head rel_exp. eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. diff --git a/theories/Core/Completeness/LogicalRelation/Tactics.v b/theories/Core/Completeness/LogicalRelation/Tactics.v index 89400fc2..439d2aec 100644 --- a/theories/Core/Completeness/LogicalRelation/Tactics.v +++ b/theories/Core/Completeness/LogicalRelation/Tactics.v @@ -1,3 +1,8 @@ +From Coq Require Import Morphisms_Relations RelationClasses. +From Mcltt Require Import Base LibTactics. +From Mcltt.Core Require Import Evaluation PER System. +Import Domain_Notations. + Ltac eexists_rel_exp := eexists; eexists; [eassumption |]; @@ -8,3 +13,10 @@ Ltac eexists_rel_subst := eexists; [eassumption |]; eexists; eexists; [eassumption |]. + +Ltac invert_rel_typ_body := + dir_inversion_by_head eval_exp; subst; + match_by_head per_univ_elem ltac:(fun H => directed invert_per_univ_elem H); subst; + clear_refl_eqs; + handle_per_univ_elem_irrel; + try rewrite <- per_univ_elem_equation_1 in *. diff --git a/theories/Core/Completeness/NatCases.v b/theories/Core/Completeness/NatCases.v index fc12a768..46b015b9 100644 --- a/theories/Core/Completeness/NatCases.v +++ b/theories/Core/Completeness/NatCases.v @@ -71,12 +71,7 @@ Proof. (on_all_hyp: destruct_rel_by_assumption env_relΓ). (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ ℕ }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ ℕ }}} d{{{ ℕ }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence - end. + invert_rel_typ_body. destruct_by_head rel_exp. eexists. split; [> econstructor; only 1-2: repeat econstructor ..]; eauto. @@ -94,12 +89,7 @@ Proof. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ ℕ }}}); subst. - match goal with - | H : per_univ_elem _ _ d{{{ ℕ }}} d{{{ ℕ }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence - end. + invert_rel_typ_body. destruct_by_head rel_exp. eexists. split; [> econstructor; only 1-2: repeat econstructor ..]; eauto. diff --git a/theories/Core/Completeness/TermStructureCases.v b/theories/Core/Completeness/TermStructureCases.v index db0a81b7..fe408384 100644 --- a/theories/Core/Completeness/TermStructureCases.v +++ b/theories/Core/Completeness/TermStructureCases.v @@ -92,14 +92,7 @@ Proof. (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_exp. destruct_by_head rel_typ. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - handle_per_univ_elem_irrel. - match goal with - | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => - invert_per_univ_elem H; - apply_relation_equivalence; - clear_refl_eqs - end. + invert_rel_typ_body. destruct_conjs. handle_per_univ_elem_irrel. eexists. @@ -179,9 +172,7 @@ Proof. eexists_rel_exp. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). - evar (j : nat). - eexists (per_univ j). - subst j. + eexists (per_univ _). split. + econstructor; only 1-2: repeat econstructor; try eassumption. per_univ_elem_econstructor; eauto. diff --git a/theories/Core/Completeness/UniverseCases.v b/theories/Core/Completeness/UniverseCases.v index 62c8b4ec..6a42d11a 100644 --- a/theories/Core/Completeness/UniverseCases.v +++ b/theories/Core/Completeness/UniverseCases.v @@ -43,8 +43,7 @@ Proof. (on_all_hyp: destruct_rel_by_assumption env_rel). inversion_by_head rel_typ. inversion_by_head rel_exp. - inversion_by_head (eval_exp {{{ Type@i }}}); subst. - match_by_head per_univ_elem invert_per_univ_elem; subst. + invert_rel_typ_body. handle_per_univ_elem_irrel. destruct_conjs. match_by_head per_univ_elem ltac:(fun H => apply per_univ_elem_cumu in H). diff --git a/theories/Core/Completeness/VariableCases.v b/theories/Core/Completeness/VariableCases.v index c47beb3c..cfa6f568 100644 --- a/theories/Core/Completeness/VariableCases.v +++ b/theories/Core/Completeness/VariableCases.v @@ -27,7 +27,7 @@ Proof with solve [repeat econstructor; mauto]. - split; econstructor... - destruct_by_head rel_typ. destruct_by_head rel_exp. - inversion_by_head (eval_exp {{{ #n }}}); subst. + dir_inversion_by_head eval_exp; subst. split; econstructor; simpl... Qed. @@ -57,7 +57,7 @@ Proof. (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. destruct_by_head rel_exp. - inversion_by_head (eval_exp {{{ A[σ] }}}); subst. + dir_inversion_by_head eval_exp; subst. functional_eval_rewrite_clear. eexists. split; [> econstructor; only 1-2: repeat econstructor ..]; eassumption. @@ -83,8 +83,7 @@ Proof. (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_typ. destruct_by_head rel_exp. - inversion_by_head (eval_exp {{{ A[σ] }}}); subst. - inversion_by_head (eval_exp {{{ # x }}}); subst. + dir_inversion_by_head eval_exp; subst. functional_eval_rewrite_clear. eexists. split; [> econstructor; only 1-2: repeat econstructor ..]; eassumption. @@ -107,7 +106,7 @@ Proof. (on_all_hyp: destruct_rel_by_assumption tail_rel). destruct_by_head rel_typ. destruct_by_head rel_exp. - inversion_by_head (eval_exp {{{ #x }}}); subst. + dir_inversion_by_head eval_exp; subst. eexists. split; [> econstructor; only 1-2: repeat econstructor ..]; eassumption. Qed. diff --git a/theories/LibTactics.v b/theories/LibTactics.v index 5f7225e4..6b7ae520 100644 --- a/theories/LibTactics.v +++ b/theories/LibTactics.v @@ -98,12 +98,17 @@ Ltac clear_dups := repeat find_dup_hyp ltac:(fun H H' _ => clear H || clear H') ltac:(idtac). -Ltac progressive_invert H := +Ltac directed tac := let ng := numgoals in - (* dependent destruction is more general than inversion *) - dependent destruction H; + tac; let ng' := numgoals in - guard ng = ng'. + guard ng' <= ng. + +Tactic Notation "directed" tactic2(tac) := directed tac. + +Ltac progressive_invert H := + (* dependent destruction is more general than inversion *) + directed dependent destruction H. Ltac clean_replace_by exp0 exp1 tac := tryif unify exp0 exp1 @@ -133,8 +138,11 @@ Ltac match_by_head1 head tac := Ltac match_by_head head tac := repeat (match_by_head1 head ltac:(fun H => tac H; try mark H)); unmark_all. Ltac inversion_by_head head := match_by_head head ltac:(fun H => inversion H). +Ltac dir_inversion_by_head head := match_by_head head ltac:(fun H => directed inversion H). Ltac inversion_clear_by_head head := match_by_head head ltac:(fun H => inversion_clear H). +Ltac dir_inversion_clear_by_head head := match_by_head head ltac:(fun H => directed inversion_clear H). Ltac destruct_by_head head := match_by_head head ltac:(fun H => destruct H). +Ltac dir_destruct_by_head head := match_by_head head ltac:(fun H => directed destruct H). (** McLTT automation *) From 501808eed8c72175a008324af6288443ff5b539e Mon Sep 17 00:00:00 2001 From: "Junyoung/\"Clare\" Jang" <jjc9310@gmail.com> Date: Tue, 21 May 2024 18:50:43 -0400 Subject: [PATCH 6/8] Update proofs --- theories/Core/Completeness/FunctionCases.v | 45 ++++++++++--------- .../Core/Completeness/SubstitutionCases.v | 12 +++-- .../Core/Completeness/TermStructureCases.v | 4 +- theories/Core/Completeness/UniverseCases.v | 13 +++--- theories/Core/Completeness/VariableCases.v | 6 ++- theories/Core/Semantic/PER/Lemmas.v | 34 ++++++++++++++ 6 files changed, 79 insertions(+), 35 deletions(-) diff --git a/theories/Core/Completeness/FunctionCases.v b/theories/Core/Completeness/FunctionCases.v index e43f20bb..5fefea0d 100644 --- a/theories/Core/Completeness/FunctionCases.v +++ b/theories/Core/Completeness/FunctionCases.v @@ -48,13 +48,13 @@ Proof with intuition. pose proof (@relation_equivalence_pointwise env). intros * [env_relΓ] [env_relΓA]. destruct_conjs. - pose (env_relΓ0 := env_relΓ). pose (env_relΓA0 := env_relΓA). - inversion_by_head (per_ctx_env env_relΓA); subst. - handle_per_ctx_env_irrel. + match_by_head (per_ctx_env env_relΓA) + ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + destruct_conjs. eexists_rel_exp. intros. - (on_all_hyp: destruct_rel_by_assumption tail_rel). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. invert_rel_typ_body. destruct_by_head rel_exp. @@ -85,16 +85,18 @@ Lemma rel_exp_pi_sub : forall {i Γ σ Δ A B}, Proof with intuition. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [env_relΓ] [] [env_relΔA]. + intros * [env_relΓ] [env_relΔ] [env_relΔA]. destruct_conjs. pose (env_relΔA0 := env_relΔA). - inversion_by_head (per_ctx_env env_relΔA); subst. + match_by_head (per_ctx_env env_relΔA) + ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + destruct_conjs. handle_per_ctx_env_irrel. eexists_rel_exp. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). - assert {{ Dom o' ≈ o' ∈ tail_rel }} by (etransitivity; [symmetry|]; eassumption). - (on_all_hyp: destruct_rel_by_assumption tail_rel). + assert {{ Dom o' ≈ o' ∈ env_relΔ }} by (etransitivity; [symmetry|]; eassumption). + (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_typ. invert_rel_typ_body. destruct_by_head rel_exp. @@ -128,13 +130,14 @@ Proof with intuition. pose proof (@relation_equivalence_pointwise env). intros * [env_relΓ] [env_relΓA]. destruct_conjs. - pose (env_relΓ0 := env_relΓ). pose (env_relΓA0 := env_relΓA). - inversion_by_head (per_ctx_env env_relΓA); subst. + match_by_head (per_ctx_env env_relΓA) + ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + destruct_conjs. handle_per_ctx_env_irrel. eexists_rel_exp. intros. - (on_all_hyp: destruct_rel_by_assumption tail_rel). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. invert_rel_typ_body. destruct_by_head rel_exp. @@ -169,16 +172,17 @@ Lemma rel_exp_fn_sub : forall {Γ σ Δ A M B}, Proof with intuition. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [env_relΓ] [env_relΔA]. + intros * [env_relΓ [? [env_relΔ]]] [env_relΔA]. destruct_conjs. - pose (env_relΓ0 := env_relΓ). pose (env_relΔA0 := env_relΔA). - inversion_by_head (per_ctx_env env_relΔA); subst. + match_by_head (per_ctx_env env_relΔA) + ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + destruct_conjs. handle_per_ctx_env_irrel. eexists_rel_exp. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). - (on_all_hyp: destruct_rel_by_assumption tail_rel). + (on_all_hyp: destruct_rel_by_assumption env_relΔ). eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; @@ -209,7 +213,7 @@ Lemma rel_exp_app_cong : forall {Γ M M' A B N N'}, Proof with intuition. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [env_relΓ] [env_relΓ']. + intros * [env_relΓ] []. destruct_conjs. pose (env_relΓ0 := env_relΓ). handle_per_ctx_env_irrel. @@ -244,7 +248,7 @@ Lemma rel_exp_app_sub : forall {Γ σ Δ M A B N}, Proof with intuition. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [env_relΓ] [env_relΔ] [env_relΔ']. + intros * [env_relΓ] [env_relΔ] []. destruct_conjs. pose (env_relΓ0 := env_relΓ). pose (env_relΔ0 := env_relΔ). @@ -275,13 +279,14 @@ Proof with intuition. pose proof (@relation_equivalence_pointwise env). intros * [env_relΓA] [env_relΓ]. destruct_conjs. - pose (env_relΓ0 := env_relΓ). pose (env_relΓA0 := env_relΓA). - inversion_by_head (per_ctx_env env_relΓA); subst. + match_by_head (per_ctx_env env_relΓA) + ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + destruct_conjs. handle_per_ctx_env_irrel. eexists_rel_exp. intros. - (on_all_hyp: destruct_rel_by_assumption tail_rel). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. handle_per_univ_elem_irrel. destruct_by_head rel_exp. diff --git a/theories/Core/Completeness/SubstitutionCases.v b/theories/Core/Completeness/SubstitutionCases.v index c38d3952..88a841bc 100644 --- a/theories/Core/Completeness/SubstitutionCases.v +++ b/theories/Core/Completeness/SubstitutionCases.v @@ -57,11 +57,13 @@ Proof with intuition. pose (env_relΔA0 := env_relΔA). handle_per_ctx_env_irrel. eexists_rel_subst. - inversion_by_head (per_ctx_env env_relΔA); subst. + match_by_head (per_ctx_env env_relΔA) + ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + destruct_conjs. handle_per_ctx_env_irrel. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). - (on_all_hyp: destruct_rel_by_assumption tail_rel). + (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ A[σ] }}}); subst. handle_per_univ_elem_irrel. @@ -132,12 +134,14 @@ Proof with intuition. pose (env_relΓ''A0 := env_relΓ''A). handle_per_ctx_env_irrel. eexists_rel_subst. - inversion_by_head (per_ctx_env env_relΓ''A); subst. + match_by_head (per_ctx_env env_relΓ''A) + ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + destruct_conjs. handle_per_ctx_env_irrel. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). (on_all_hyp: destruct_rel_by_assumption env_relΓ'). - (on_all_hyp: destruct_rel_by_assumption tail_rel). + (on_all_hyp: destruct_rel_by_assumption env_relΓ''). destruct_by_head rel_typ. inversion_by_head (eval_exp {{{ A[σ] }}}); subst. handle_per_univ_elem_irrel. diff --git a/theories/Core/Completeness/TermStructureCases.v b/theories/Core/Completeness/TermStructureCases.v index fe408384..f28b1a80 100644 --- a/theories/Core/Completeness/TermStructureCases.v +++ b/theories/Core/Completeness/TermStructureCases.v @@ -82,7 +82,7 @@ Lemma rel_exp_conv : forall {Γ M M' A A' i}, Proof. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [env_relΓ] [env_relΓ']. + intros * [env_relΓ] []. destruct_conjs. pose (env_relΓ0 := env_relΓ). handle_per_ctx_env_irrel. @@ -127,7 +127,7 @@ Lemma rel_exp_trans : forall {Γ M1 M2 M3 A}, Proof. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [env_relΓ] [env_relΓ']. + intros * [env_relΓ] []. destruct_conjs. pose (env_relΓ0 := env_relΓ). handle_per_ctx_env_irrel. diff --git a/theories/Core/Completeness/UniverseCases.v b/theories/Core/Completeness/UniverseCases.v index 6a42d11a..8011da0b 100644 --- a/theories/Core/Completeness/UniverseCases.v +++ b/theories/Core/Completeness/UniverseCases.v @@ -19,12 +19,12 @@ Lemma rel_exp_typ_sub : forall {i Γ σ Δ}, {{ Γ ⊨s σ : Δ }} -> {{ Γ ⊨ Type@i[σ] ≈ Type@i : Type@(S i) }}. Proof. - intros * [env_rel]. + intros * [env_relΓ]. destruct_conjs. eexists_rel_exp. intros. eexists (per_univ _). - (on_all_hyp: destruct_rel_by_assumption env_rel). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). split; [> econstructor; only 1-2: repeat econstructor; eauto ..]; [| eexists (per_univ _)]; per_univ_elem_econstructor; eauto; apply Equivalence_Reflexive. Qed. @@ -35,19 +35,18 @@ Lemma rel_exp_cumu : forall {i Γ A A'}, Proof. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). - intros * [env_rel]. + intros * [env_relΓ]. destruct_conjs. eexists_rel_exp. intros. - eexists (per_univ _). - (on_all_hyp: destruct_rel_by_assumption env_rel). + exists (per_univ (S i)). + (on_all_hyp: destruct_rel_by_assumption env_relΓ). inversion_by_head rel_typ. inversion_by_head rel_exp. invert_rel_typ_body. - handle_per_univ_elem_irrel. destruct_conjs. match_by_head per_univ_elem ltac:(fun H => apply per_univ_elem_cumu in H). - split; [> econstructor; only 1-2: repeat econstructor; eauto ..]; [| eexists; eauto]. + split; [> econstructor; only 1-2: repeat econstructor ..]; eauto; [| eexists; eauto]. per_univ_elem_econstructor; eauto. reflexivity. Qed. diff --git a/theories/Core/Completeness/VariableCases.v b/theories/Core/Completeness/VariableCases.v index cfa6f568..8442e1db 100644 --- a/theories/Core/Completeness/VariableCases.v +++ b/theories/Core/Completeness/VariableCases.v @@ -102,8 +102,10 @@ Proof. destruct_conjs. eexists_rel_exp. apply_relation_equivalence. - intros ? ? []. - (on_all_hyp: destruct_rel_by_assumption tail_rel). + intros. + destruct_conjs. + rename tail_rel into env_relΓ. + (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. destruct_by_head rel_exp. dir_inversion_by_head eval_exp; subst. diff --git a/theories/Core/Semantic/PER/Lemmas.v b/theories/Core/Semantic/PER/Lemmas.v index 351a2e3c..98e10411 100644 --- a/theories/Core/Semantic/PER/Lemmas.v +++ b/theories/Core/Semantic/PER/Lemmas.v @@ -733,3 +733,37 @@ Proof. - auto using (per_env_sym _ _ _ _ _ H). - eauto using (per_env_trans _ _ _ _ _ _ H). Qed. + +Lemma per_ctx_env_cons_clear_inversion : forall {Γ Γ' env_relΓ A A' env_relΓA}, + {{ EF Γ ≈ Γ' ∈ per_ctx_env ↘ env_relΓ }} -> + {{ EF Γ, A ≈ Γ', A' ∈ per_ctx_env ↘ env_relΓA }} -> + exists i (head_rel : forall {p p'} (equiv_p_p' : {{ Dom p ≈ p' ∈ env_relΓ }}), relation domain), + (forall {p p'} (equiv_p_p' : {{ Dom p ≈ p' ∈ env_relΓ }}), + rel_typ i A p A' p' (head_rel equiv_p_p')) /\ + (env_relΓA <~> fun p p' => + exists (equiv_p_drop_p'_drop : {{ Dom p ↯ ≈ p' ↯ ∈ env_relΓ }}), + {{ Dom ~(p 0) ≈ ~(p' 0) ∈ head_rel equiv_p_drop_p'_drop }}). +Proof with intuition. + intros * HΓ HΓA. + inversion HΓA; subst. + handle_per_ctx_env_irrel. + eexists. + eexists. + split; intros. + - instantiate (1 := fun p p' (equiv_p_p' : env_relΓ p p') m m' => + forall a a' R, + {{ ⟦ A ⟧ p ↘ a }} -> + {{ ⟦ A' ⟧ p' ↘ a' }} -> + {{ DF a ≈ a' ∈ per_univ_elem i ↘ R }} -> + {{ Dom m ≈ m' ∈ R }}). + assert (tail_rel p p') by intuition. + (on_all_hyp: destruct_rel_by_assumption tail_rel). + econstructor; eauto. + apply -> per_univ_elem_morphism_iff; eauto. + split; intros; handle_per_univ_elem_irrel... + - intros o o'. + split; intros; destruct_conjs; + assert {{ Dom o ↯ ≈ o' ↯ ∈ tail_rel }} by intuition; + (on_all_hyp: destruct_rel_by_assumption tail_rel); + eexists; intros; handle_per_univ_elem_irrel; intuition. +Qed. From eba9e90b3a33de119435da293e776f3d232f18f7 Mon Sep 17 00:00:00 2001 From: Junyoung/Clare Jang <jjc9310@gmail.com> Date: Wed, 22 May 2024 14:52:32 -0400 Subject: [PATCH 7/8] Update PER tactic --- theories/Core/Completeness/ContextCases.v | 12 +- theories/Core/Completeness/FunctionCases.v | 72 ++++----- .../Completeness/LogicalRelation/Tactics.v | 1 + .../Core/Completeness/SubstitutionCases.v | 6 +- theories/Core/Semantic/PER/CoreTactics.v | 4 +- theories/Core/Semantic/PER/Lemmas.v | 147 +++++++++++++----- 6 files changed, 150 insertions(+), 92 deletions(-) diff --git a/theories/Core/Completeness/ContextCases.v b/theories/Core/Completeness/ContextCases.v index 4221c87c..0855e47b 100644 --- a/theories/Core/Completeness/ContextCases.v +++ b/theories/Core/Completeness/ContextCases.v @@ -22,12 +22,10 @@ Proof with intuition. destruct_conjs. handle_per_ctx_env_irrel. eexists. - econstructor; eauto with typeclass_instances. + per_ctx_env_econstructor; eauto. - instantiate (1 := fun p p' (equiv_p_p' : env_relΓ p p') m m' => - forall i a a' R, - {{ ⟦ A ⟧ p ↘ a }} -> - {{ ⟦ A' ⟧ p' ↘ a' }} -> - per_univ_elem i R a a' -> + forall i R, + rel_typ i A p A' p' R -> R m m'). intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). @@ -37,6 +35,8 @@ Proof with intuition. destruct_conjs. econstructor; eauto. apply -> per_univ_elem_morphism_iff; eauto. - split; intros; handle_per_univ_elem_irrel... + split; intros; destruct_by_head rel_typ; handle_per_univ_elem_irrel... + eapply H12. + econstructor... - apply Equivalence_Reflexive. Qed. diff --git a/theories/Core/Completeness/FunctionCases.v b/theories/Core/Completeness/FunctionCases.v index 5fefea0d..8fe562cf 100644 --- a/theories/Core/Completeness/FunctionCases.v +++ b/theories/Core/Completeness/FunctionCases.v @@ -12,31 +12,28 @@ Ltac extract_output_info_with p c p' c' env_rel := destruct_by_head rel_typ; destruct_by_head rel_exp). -Lemma rel_exp_pi_core : forall {i p o B p' o' B'} {tail_rel : relation env} - (head_rel : forall p p', {{ Dom p ≈ p' ∈ tail_rel }} -> relation domain) - (equiv_p_p' : {{ Dom p ≈ p' ∈ tail_rel }}) - {out_rel}, +Lemma rel_exp_pi_core : forall {i o B o' B' R out_rel}, (forall c c', - head_rel p p' equiv_p_p' c c' -> + R c c' -> rel_exp B d{{{ o ↦ c }}} B' d{{{ o' ↦ c' }}} (per_univ i)) -> (* We use this equality to make unification on `out_rel` works *) - (out_rel = fun c c' (equiv_c_c' : head_rel p p' equiv_p_p' c c') m m' => - forall b b' R, - {{ ⟦ B ⟧ o ↦ c ↘ b }} -> - {{ ⟦ B' ⟧ o' ↦ c' ↘ b' }} -> - per_univ_elem i R b b' -> R m m') -> - (forall c c' (equiv_c_c' : head_rel p p' equiv_p_p' c c'), rel_typ i B d{{{ o ↦ c }}} B' d{{{ o' ↦ c' }}} (out_rel c c' equiv_c_c')). + (out_rel = fun c c' (equiv_c_c' : R c c') m m' => + forall R', + rel_typ i B d{{{ o ↦ c }}} B' d{{{ o' ↦ c' }}} R' -> + R' m m') -> + (forall c c' (equiv_c_c' : R c c'), rel_typ i B d{{{ o ↦ c }}} B' d{{{ o' ↦ c' }}} (out_rel c c' equiv_c_c')). Proof with intuition. pose proof (@relation_equivalence_pointwise domain). pose proof (@relation_equivalence_pointwise env). intros. subst. - (on_all_hyp: destruct_rel_by_assumption (head_rel p p' equiv_p_p')). - destruct_by_head rel_exp. + (on_all_hyp: destruct_rel_by_assumption R). econstructor; mauto. destruct_by_head per_univ. apply -> per_univ_elem_morphism_iff; eauto. - split; intros; handle_per_univ_elem_irrel... + split; intros; destruct_by_head rel_typ; handle_per_univ_elem_irrel... + eapply H5. + econstructor... Qed. Lemma rel_exp_pi_cong : forall {i Γ A A' B B'}, @@ -49,9 +46,7 @@ Proof with intuition. intros * [env_relΓ] [env_relΓA]. destruct_conjs. pose (env_relΓA0 := env_relΓA). - match_by_head (per_ctx_env env_relΓA) - ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). - destruct_conjs. + match_by_head (per_ctx_env env_relΓA) invert_per_ctx_env. eexists_rel_exp. intros. (on_all_hyp: destruct_rel_by_assumption env_relΓ). @@ -63,7 +58,7 @@ Proof with intuition. eexists (per_univ _). split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. eexists. - per_univ_elem_econstructor; eauto with typeclass_instances. + per_univ_elem_econstructor; eauto. - intros. eapply rel_exp_pi_core; eauto. + clear dependent c. @@ -87,10 +82,9 @@ Proof with intuition. pose proof (@relation_equivalence_pointwise env). intros * [env_relΓ] [env_relΔ] [env_relΔA]. destruct_conjs. + pose (env_relΔ0 := env_relΔ). pose (env_relΔA0 := env_relΔA). - match_by_head (per_ctx_env env_relΔA) - ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). - destruct_conjs. + match_by_head (per_ctx_env env_relΔA) invert_per_ctx_env. handle_per_ctx_env_irrel. eexists_rel_exp. intros. @@ -105,7 +99,7 @@ Proof with intuition. eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. eexists. - per_univ_elem_econstructor; eauto with typeclass_instances. + per_univ_elem_econstructor; eauto. - intros. eapply rel_exp_pi_core; eauto. + clear dependent c. @@ -131,9 +125,7 @@ Proof with intuition. intros * [env_relΓ] [env_relΓA]. destruct_conjs. pose (env_relΓA0 := env_relΓA). - match_by_head (per_ctx_env env_relΓA) - ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). - destruct_conjs. + match_by_head (per_ctx_env env_relΓA) invert_per_ctx_env. handle_per_ctx_env_irrel. eexists_rel_exp. intros. @@ -144,8 +136,7 @@ Proof with intuition. functional_eval_rewrite_clear. eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. - - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; - eauto with typeclass_instances. + - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | |]; eauto. + intros. eapply rel_exp_pi_core; eauto. * clear dependent c. @@ -162,6 +153,7 @@ Proof with intuition. extract_output_info_with p c p' c' env_relΓA. econstructor; only 1-2: repeat econstructor; eauto. intros. + destruct_by_head rel_typ. handle_per_univ_elem_irrel... Qed. @@ -175,9 +167,7 @@ Proof with intuition. intros * [env_relΓ [? [env_relΔ]]] [env_relΔA]. destruct_conjs. pose (env_relΔA0 := env_relΔA). - match_by_head (per_ctx_env env_relΔA) - ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). - destruct_conjs. + match_by_head (per_ctx_env env_relΔA) invert_per_ctx_env. handle_per_ctx_env_irrel. eexists_rel_exp. intros. @@ -185,8 +175,7 @@ Proof with intuition. (on_all_hyp: destruct_rel_by_assumption env_relΔ). eexists. split; [> econstructor; only 1-2: repeat econstructor; eauto ..]. - - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | | |]; - eauto with typeclass_instances. + - per_univ_elem_econstructor; [eapply per_univ_elem_cumu_max_left | |]; eauto. + intros. eapply rel_exp_pi_core; eauto. * clear dependent c. @@ -201,8 +190,9 @@ Proof with intuition. apply Equivalence_Reflexive. - intros ? **. extract_output_info_with o c o' c' env_relΔA. - econstructor; only 1-2: repeat econstructor; simpl; mauto. + econstructor; only 1-2: repeat econstructor; mauto. intros. + destruct_by_head rel_typ. handle_per_univ_elem_irrel... Qed. @@ -222,17 +212,14 @@ Proof with intuition. assert (equiv_p'_p' : env_relΓ p' p') by (etransitivity; [symmetry |]; eauto). (on_all_hyp: destruct_rel_by_assumption env_relΓ). destruct_by_head rel_typ. - functional_eval_rewrite_clear. - invert_rel_typ_body. handle_per_univ_elem_irrel. + invert_rel_typ_body. destruct_by_head rel_exp. functional_eval_rewrite_clear. - assert (in_rel0 m1 m2) by (etransitivity; [| symmetry]; eauto). + rename x into in_rel. + assert (in_rel m1 m2) by (etransitivity; [| symmetry]; eauto). assert (in_rel m1 m'2) by intuition. - assert (in_rel m1 m2) by intuition. (on_all_hyp: destruct_rel_by_assumption in_rel). - (on_all_hyp: destruct_rel_by_assumption in_rel0). - (on_all_hyp_rev: destruct_rel_by_assumption in_rel0). handle_per_univ_elem_irrel. eexists. split; [> econstructor; only 1-2: econstructor ..]. @@ -259,9 +246,8 @@ Proof with intuition. (on_all_hyp: destruct_rel_by_assumption env_relΔ). destruct_by_head rel_typ. invert_rel_typ_body. - handle_per_univ_elem_irrel. destruct_by_head rel_exp. - functional_eval_rewrite_clear. + rename x into in_rel. (on_all_hyp_rev: destruct_rel_by_assumption in_rel). eexists. split; [> econstructor; only 1-2: econstructor ..]. @@ -280,9 +266,7 @@ Proof with intuition. intros * [env_relΓA] [env_relΓ]. destruct_conjs. pose (env_relΓA0 := env_relΓA). - match_by_head (per_ctx_env env_relΓA) - ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). - destruct_conjs. + match_by_head (per_ctx_env env_relΓA) invert_per_ctx_env. handle_per_ctx_env_irrel. eexists_rel_exp. intros. diff --git a/theories/Core/Completeness/LogicalRelation/Tactics.v b/theories/Core/Completeness/LogicalRelation/Tactics.v index 439d2aec..3c1e04c5 100644 --- a/theories/Core/Completeness/LogicalRelation/Tactics.v +++ b/theories/Core/Completeness/LogicalRelation/Tactics.v @@ -16,6 +16,7 @@ Ltac eexists_rel_subst := Ltac invert_rel_typ_body := dir_inversion_by_head eval_exp; subst; + functional_eval_rewrite_clear; match_by_head per_univ_elem ltac:(fun H => directed invert_per_univ_elem H); subst; clear_refl_eqs; handle_per_univ_elem_irrel; diff --git a/theories/Core/Completeness/SubstitutionCases.v b/theories/Core/Completeness/SubstitutionCases.v index 88a841bc..577cefd6 100644 --- a/theories/Core/Completeness/SubstitutionCases.v +++ b/theories/Core/Completeness/SubstitutionCases.v @@ -57,8 +57,7 @@ Proof with intuition. pose (env_relΔA0 := env_relΔA). handle_per_ctx_env_irrel. eexists_rel_subst. - match_by_head (per_ctx_env env_relΔA) - ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + match_by_head (per_ctx_env env_relΔA) invert_per_ctx_env. destruct_conjs. handle_per_ctx_env_irrel. intros. @@ -134,8 +133,7 @@ Proof with intuition. pose (env_relΓ''A0 := env_relΓ''A). handle_per_ctx_env_irrel. eexists_rel_subst. - match_by_head (per_ctx_env env_relΓ''A) - ltac:(fun H => eapply per_ctx_env_cons_clear_inversion in H; [| eassumption]). + match_by_head (per_ctx_env env_relΓ''A) invert_per_ctx_env. destruct_conjs. handle_per_ctx_env_irrel. intros. diff --git a/theories/Core/Semantic/PER/CoreTactics.v b/theories/Core/Semantic/PER/CoreTactics.v index 4bf94b82..fb82b100 100644 --- a/theories/Core/Semantic/PER/CoreTactics.v +++ b/theories/Core/Semantic/PER/CoreTactics.v @@ -37,13 +37,13 @@ Ltac destruct_rel_typ := (** Universe/Element PER Helper Tactics *) -Ltac invert_per_univ_elem H := +Ltac basic_invert_per_univ_elem H := simp per_univ_elem in H; inversion H; subst; try rewrite <- per_univ_elem_equation_1 in *. -Ltac per_univ_elem_econstructor := +Ltac basic_per_univ_elem_econstructor := simp per_univ_elem; econstructor; try rewrite <- per_univ_elem_equation_1 in *. diff --git a/theories/Core/Semantic/PER/Lemmas.v b/theories/Core/Semantic/PER/Lemmas.v index 98e10411..61642ae7 100644 --- a/theories/Core/Semantic/PER/Lemmas.v +++ b/theories/Core/Semantic/PER/Lemmas.v @@ -1,4 +1,4 @@ -From Coq Require Import Lia Morphisms Morphisms_Prop Morphisms_Relations PeanoNat Relation_Definitions RelationClasses. +From Coq Require Import Equivalence Lia Morphisms Morphisms_Prop Morphisms_Relations PeanoNat Relation_Definitions RelationClasses. From Equations Require Import Equations. From Mcltt Require Import Axioms Base LibTactics. From Mcltt.Core Require Import Evaluation PER.Definitions PER.CoreTactics Readback. @@ -184,7 +184,7 @@ Proof with mautosolve. simpl. intros R R' HRR'. split; intros Horig; [gen R' | gen R]; - induction Horig using per_univ_elem_ind; per_univ_elem_econstructor; eauto; + induction Horig using per_univ_elem_ind; basic_per_univ_elem_econstructor; eauto; try (etransitivity; [symmetry + idtac|]; eassumption); intros; destruct_rel_mod_eval; @@ -244,7 +244,7 @@ Proof with (destruct_rel_mod_eval; destruct_rel_mod_app; functional_eval_rewrite remember a as a' in |- *. gen a' b' R'. induction Horig using per_univ_elem_ind; intros * Heq Hright; - subst; invert_per_univ_elem Hright; unfold per_univ; + subst; basic_invert_per_univ_elem Hright; unfold per_univ; intros; apply_relation_equivalence; try reflexivity. @@ -288,16 +288,16 @@ Proof with mautosolve. destruct_by_head per_univ. eexists. eapply proj1... - - split; [per_univ_elem_econstructor | intros; apply_relation_equivalence]... + - split; [basic_per_univ_elem_econstructor | intros; apply_relation_equivalence]... - destruct_conjs. split. - + per_univ_elem_econstructor; eauto. + + basic_per_univ_elem_econstructor; eauto. intros. assert (in_rel c' c) by eauto. assert (in_rel c c) by (etransitivity; eassumption). destruct_rel_mod_eval. functional_eval_rewrite_clear. - econstructor; mauto. + econstructor; eauto. per_univ_elem_right_irrel_assert. apply_relation_equivalence. eassumption. @@ -308,7 +308,7 @@ Proof with mautosolve. destruct_rel_mod_eval. destruct_rel_mod_app. functional_eval_rewrite_clear. - econstructor; mauto. + econstructor; eauto. per_univ_elem_right_irrel_assert. intuition. - split; [econstructor | intros; apply_relation_equivalence]... @@ -397,11 +397,11 @@ Lemma per_univ_elem_trans : forall i R A1 A2, R a1 a2 -> R a2 a3 -> R a1 a3). -Proof with (per_univ_elem_econstructor; mautosolve). +Proof with (basic_per_univ_elem_econstructor; mautosolve). pose proof (@relation_equivalence_pointwise domain). induction 1 using per_univ_elem_ind; [> split; - [ intros * HT2; invert_per_univ_elem HT2; clear HT2 + [ intros * HT2; basic_invert_per_univ_elem HT2; clear HT2 | intros * HTR1 HTR2; apply_relation_equivalence ] ..]; mauto. - (* univ case *) subst. @@ -415,7 +415,7 @@ Proof with (per_univ_elem_econstructor; mautosolve). idtac... - (* pi case *) destruct_conjs. - per_univ_elem_econstructor; eauto. + basic_per_univ_elem_econstructor; eauto. + handle_per_univ_elem_irrel. intuition. + intros. @@ -474,48 +474,97 @@ Proof. Qed. (* This lemma gets rid of the unnecessary PER premise. *) -Lemma per_univ_elem_core_pi' : - forall i A p B A' p' B' elem_rel +Lemma per_univ_elem_pi' : + forall i a a' p B p' B' (in_rel : relation domain) (out_rel : forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), relation domain) - (equiv_a_a' : {{ DF A ≈ A' ∈ per_univ_elem i ↘ in_rel}}), + elem_rel, + {{ DF a ≈ a' ∈ per_univ_elem i ↘ in_rel}} -> (forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), rel_mod_eval (per_univ_elem i) B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} (out_rel equiv_c_c')) -> (elem_rel <~> fun f f' => forall c c' (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), rel_mod_app f c f' c' (out_rel equiv_c_c')) -> - {{ DF Π A p B ≈ Π A' p' B' ∈ per_univ_elem i ↘ elem_rel }}. + {{ DF Π a p B ≈ Π a' p' B' ∈ per_univ_elem i ↘ elem_rel }}. Proof. intros. - per_univ_elem_econstructor; eauto. + basic_per_univ_elem_econstructor; eauto. typeclasses eauto. Qed. +Ltac per_univ_elem_econstructor := + (repeat intro; hnf; eapply per_univ_elem_pi') + basic_per_univ_elem_econstructor. + +#[export] +Hint Resolve per_univ_elem_pi' : mcltt. + +Lemma per_univ_elem_pi_clean_inversion : forall {i j a a' in_rel p p' B B' elem_rel}, + {{ DF a ≈ a' ∈ per_univ_elem i ↘ in_rel }} -> + {{ DF Π a p B ≈ Π a' p' B' ∈ per_univ_elem j ↘ elem_rel }} -> + exists (out_rel : forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), relation domain), + (forall c c' (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), + rel_mod_eval (per_univ_elem j) B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} (out_rel equiv_c_c')) /\ + (elem_rel <~> fun f f' => forall c c' (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), rel_mod_app f c f' c' (out_rel equiv_c_c')). +Proof. + intros * Ha HΠ. + basic_invert_per_univ_elem HΠ. + handle_per_univ_elem_irrel. + eexists. + split. + - instantiate (1 := fun c c' (equiv_c_c' : in_rel c c') m m' => + forall R, + rel_typ j B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} R -> + R m m'). + intros. + assert (in_rel0 c c') by intuition. + (on_all_hyp: destruct_rel_by_assumption in_rel0). + econstructor; eauto. + apply -> per_univ_elem_morphism_iff; eauto. + split; intuition. + destruct_by_head rel_typ. + handle_per_univ_elem_irrel. + intuition. + - split; intros; + [assert (in_rel0 c c') by intuition; (on_all_hyp: destruct_rel_by_assumption in_rel0) + | assert (in_rel c c') by intuition; (on_all_hyp: destruct_rel_by_assumption in_rel)]; + econstructor; intuition. + destruct_by_head rel_typ. + handle_per_univ_elem_irrel. + intuition. +Qed. + +Ltac invert_per_univ_elem H := + (unshelve eapply (per_univ_elem_pi_clean_inversion _) in H; [| eassumption | |]; destruct H as [? []]) + + basic_invert_per_univ_elem H. + Lemma per_univ_elem_cumu : forall i a0 a1 R, {{ DF a0 ≈ a1 ∈ per_univ_elem i ↘ R }} -> {{ DF a0 ≈ a1 ∈ per_univ_elem (S i) ↘ R }}. Proof with solve [eauto]. simpl. - induction 1 using per_univ_elem_ind; subst. - - eapply per_univ_elem_core_univ'... - - per_univ_elem_econstructor... - - per_univ_elem_econstructor; mauto. - intros. - destruct_rel_mod_eval. - econstructor... - - per_univ_elem_econstructor... + induction 1 using per_univ_elem_ind; subst; + per_univ_elem_econstructor; eauto. + intros. + destruct_rel_mod_eval. + econstructor... Qed. +#[export] +Hint Resolve per_univ_elem_cumu : mcltt. + Lemma per_univ_elem_cumu_ge : forall i i' a0 a1 R, i <= i' -> {{ DF a0 ≈ a1 ∈ per_univ_elem i ↘ R }} -> {{ DF a0 ≈ a1 ∈ per_univ_elem i' ↘ R }}. -Proof with solve [eauto using per_univ_elem_cumu]. +Proof with mautosolve. induction 1... Qed. +#[export] +Hint Resolve per_univ_elem_cumu_ge : mcltt. + Lemma per_univ_elem_cumu_max_left : forall i j a0 a1 R, {{ DF a0 ≈ a1 ∈ per_univ_elem i ↘ R }} -> {{ DF a0 ≈ a1 ∈ per_univ_elem (max i j) ↘ R }}. -Proof with solve [eauto using per_univ_elem_cumu_ge]. +Proof with mautosolve. intros. assert (i <= max i j) by lia... Qed. @@ -523,7 +572,7 @@ Qed. Lemma per_univ_elem_cumu_max_right : forall i j a0 a1 R, {{ DF a0 ≈ a1 ∈ per_univ_elem j ↘ R }} -> {{ DF a0 ≈ a1 ∈ per_univ_elem (max i j) ↘ R }}. -Proof with solve [eauto using per_univ_elem_cumu_ge]. +Proof with mautosolve. intros. assert (j <= max i j) by lia... Qed. @@ -539,7 +588,7 @@ Qed. Add Parametric Morphism : per_ctx_env with signature (@relation_equivalence env) ==> (@relation_equivalence ctx) as per_ctx_env_morphism_relation_equivalence. -Proof with mautosolve. +Proof. intros * HRR' Γ Γ'. simpl. rewrite HRR'. @@ -624,7 +673,7 @@ Proof. Qed. Ltac do_per_ctx_env_irrel_assert1 := - let tactic_error o1 o2 := fail 3 "per_ctx_env_irrel equality between" o1 "and" o2 "cannot be solved by mauto" in + let tactic_error o1 o2 := fail 3 "per_ctx_env_irrel equality between" o1 "and" o2 "cannot be solved" in match goal with | H1 : {{ DF ~?Γ ≈ ~_ ∈ per_ctx_env ↘ ?R1 }}, H2 : {{ DF ~?Γ ≈ ~_ ∈ per_ctx_env ↘ ?R2 }} |- _ => @@ -734,11 +783,31 @@ Proof. - eauto using (per_env_trans _ _ _ _ _ _ H). Qed. -Lemma per_ctx_env_cons_clear_inversion : forall {Γ Γ' env_relΓ A A' env_relΓA}, +(* This lemma removes the PER argument *) +Lemma per_ctx_env_cons' : forall {Γ Γ' i A A' tail_rel} + (head_rel : forall {p p'} (equiv_p_p' : {{ Dom p ≈ p' ∈ tail_rel }}), relation domain) + env_rel, + {{ EF Γ ≈ Γ' ∈ per_ctx_env ↘ tail_rel }} -> + (forall {p p'} (equiv_p_p' : {{ Dom p ≈ p' ∈ tail_rel }}), + rel_typ i A p A' p' (head_rel equiv_p_p')) -> + (env_rel <~> fun p p' => + exists (equiv_p_drop_p'_drop : {{ Dom p ↯ ≈ p' ↯ ∈ tail_rel }}), + {{ Dom ~(p 0) ≈ ~(p' 0) ∈ head_rel equiv_p_drop_p'_drop }}) -> + {{ EF Γ, A ≈ Γ', A' ∈ per_ctx_env ↘ env_rel }}. +Proof. + intros. + econstructor; eauto. + typeclasses eauto. +Qed. + +Ltac per_ctx_env_econstructor := + (repeat intro; hnf; eapply per_ctx_env_cons') + econstructor. + +Lemma per_ctx_env_cons_clean_inversion : forall {Γ Γ' env_relΓ A A' env_relΓA}, {{ EF Γ ≈ Γ' ∈ per_ctx_env ↘ env_relΓ }} -> {{ EF Γ, A ≈ Γ', A' ∈ per_ctx_env ↘ env_relΓA }} -> exists i (head_rel : forall {p p'} (equiv_p_p' : {{ Dom p ≈ p' ∈ env_relΓ }}), relation domain), - (forall {p p'} (equiv_p_p' : {{ Dom p ≈ p' ∈ env_relΓ }}), + (forall p p' (equiv_p_p' : {{ Dom p ≈ p' ∈ env_relΓ }}), rel_typ i A p A' p' (head_rel equiv_p_p')) /\ (env_relΓA <~> fun p p' => exists (equiv_p_drop_p'_drop : {{ Dom p ↯ ≈ p' ↯ ∈ env_relΓ }}), @@ -751,19 +820,25 @@ Proof with intuition. eexists. split; intros. - instantiate (1 := fun p p' (equiv_p_p' : env_relΓ p p') m m' => - forall a a' R, - {{ ⟦ A ⟧ p ↘ a }} -> - {{ ⟦ A' ⟧ p' ↘ a' }} -> - {{ DF a ≈ a' ∈ per_univ_elem i ↘ R }} -> + forall R, + rel_typ i A p A' p' R -> {{ Dom m ≈ m' ∈ R }}). assert (tail_rel p p') by intuition. (on_all_hyp: destruct_rel_by_assumption tail_rel). econstructor; eauto. apply -> per_univ_elem_morphism_iff; eauto. - split; intros; handle_per_univ_elem_irrel... + split; intros... + destruct_by_head rel_typ. + handle_per_univ_elem_irrel... - intros o o'. split; intros; destruct_conjs; assert {{ Dom o ↯ ≈ o' ↯ ∈ tail_rel }} by intuition; (on_all_hyp: destruct_rel_by_assumption tail_rel); - eexists; intros; handle_per_univ_elem_irrel; intuition. + unshelve eexists; intros... + destruct_by_head rel_typ. + handle_per_univ_elem_irrel... Qed. + +Ltac invert_per_ctx_env H := + (unshelve eapply (per_ctx_env_cons_clean_inversion _) in H; [eassumption | |]; destruct H as [? [? []]]) + + (inversion H; subst). From b6e06184e7e3d1e4ca14af1ad3f4ab4a6639947f Mon Sep 17 00:00:00 2001 From: Junyoung/Clare Jang <jjc9310@gmail.com> Date: Tue, 21 May 2024 04:23:11 -0400 Subject: [PATCH 8/8] Defer some nat cases --- theories/Core/Completeness/NatCases.v | 118 +++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/theories/Core/Completeness/NatCases.v b/theories/Core/Completeness/NatCases.v index 46b015b9..9d3448a8 100644 --- a/theories/Core/Completeness/NatCases.v +++ b/theories/Core/Completeness/NatCases.v @@ -1,6 +1,6 @@ -From Coq Require Import Morphisms_Relations RelationClasses. +From Coq Require Import Morphisms_Relations Relation_Definitions RelationClasses. From Mcltt Require Import Base LibTactics. -From Mcltt.Core Require Import Completeness.LogicalRelation System. +From Mcltt.Core Require Import Completeness.LogicalRelation Completeness.TermStructureCases System. Import Domain_Notations. Lemma valid_exp_nat : forall {Γ i}, @@ -96,3 +96,117 @@ Proof. - per_univ_elem_econstructor; reflexivity. - econstructor; eassumption. Qed. + +Lemma eval_natrec_rel : forall {Γ env_relΓ MZ MZ' MS MS' A A' i m m'}, + {{ DF Γ ≈ Γ ∈ per_ctx_env ↘ env_relΓ }} -> + {{ Γ, ℕ ⊨ A ≈ A' : Type@i }} -> + {{ Γ ⊨ MZ ≈ MZ' : A[Id,,zero] }} -> + {{ Γ, ℕ, A ⊨ MS ≈ MS' : A[Wk∘Wk,,succ(#1)] }} -> + {{ Dom m ≈ m' ∈ per_nat }} -> + (forall p p' (equiv_p_p' : {{ Dom p ≈ p' ∈ env_relΓ }}), + forall (elem_rel : relation domain), + rel_typ i A d{{{ p ↦ m }}} A d{{{ p' ↦ m' }}} elem_rel -> + exists r r', + {{ rec m ⟦return A | zero -> MZ | succ -> MS end⟧ p ↘ r }} /\ + {{ rec m' ⟦return A' | zero -> MZ' | succ -> MS' end⟧ p' ↘ r' }} /\ + {{ Dom r ≈ r' ∈ elem_rel }}). +Proof. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * equiv_Γ_Γ HAA' [] [env_relΓℕA] equiv_m_m'. + assert {{ Γ, ℕ ⊨ A : Type@i }} as [env_relΓℕ] by (unfold valid_exp_under_ctx; etransitivity; [| symmetry]; eassumption). + destruct_conjs. + pose (env_relΓℕA0 := env_relΓℕA). + pose (env_relΓℕ0 := env_relΓℕ). + match_by_head (per_ctx_env env_relΓℕA) invert_per_ctx_env. + handle_per_ctx_env_irrel. + match_by_head (per_ctx_env env_relΓℕ) invert_per_ctx_env. + handle_per_ctx_env_irrel. + induction equiv_m_m'; intros; + destruct_by_head rel_typ; + (on_all_hyp: destruct_rel_by_assumption env_relΓ); + invert_rel_typ_body; + destruct_by_head rel_typ; + dir_inversion_by_head eval_exp; subst; + dir_inversion_by_head eval_sub; subst; + dir_inversion_by_head eval_exp; subst; + functional_eval_rewrite_clear; + destruct_by_head rel_exp; + handle_per_univ_elem_irrel. + - do 2 eexists. + repeat split; only 1-2: econstructor; eauto. + - assert {{ Dom p'2 ↦ m ≈ p'3 ↦ n ∈ env_relΓℕ }} by (apply_relation_equivalence; eexists; eauto). + (on_all_hyp: destruct_rel_by_assumption env_relΓℕ). + assert {{ Dom p'2 ↦ m ≈ p'3 ↦ n ∈ env_relΓℕ }} as HinΓℕ by (apply_relation_equivalence; eexists; eauto). + apply_relation_equivalence. + (on_all_hyp: fun H => directed destruct (H _ _ HinΓℕ) as [? []]). + destruct_by_head rel_typ. + invert_rel_typ_body. + destruct_by_head rel_exp. + destruct_conjs. + unshelve epose proof (IHequiv_m_m' _ _ equiv_p_p' _ _) as [? [? [? []]]]; [| econstructor; solve [eauto] |]. + handle_per_univ_elem_irrel. + rename x4 into r0. + rename x5 into r'0. + assert {{ Dom p'2 ↦ m ↦ r0 ≈ p'3 ↦ n ↦ r'0 ∈ env_relΓℕA }} as HinΓℕA by (apply_relation_equivalence; eexists; eauto). + apply_relation_equivalence. + (on_all_hyp: fun H => directed destruct (H _ _ HinΓℕA) as [? []]). + destruct_by_head rel_typ. + invert_rel_typ_body. + destruct_by_head rel_exp. + dir_inversion_by_head eval_sub; subst. + dir_inversion_by_head (eval_exp {{{ zero }}}); subst. + dir_inversion_by_head (eval_exp {{{ succ #1 }}}); subst. + dir_inversion_by_head (eval_exp {{{ #1 }}}); subst. + match_by_head eval_exp ltac:(fun H => simpl in H). + clear_refl_eqs. +Abort. + +Lemma rel_exp_natrec_cong : forall {Γ MZ MZ' MS MS' A A' i M M'}, + {{ Γ, ℕ ⊨ A ≈ A' : Type@i }} -> + {{ Γ ⊨ MZ ≈ MZ' : A[Id,,zero] }} -> + {{ Γ, ℕ, A ⊨ MS ≈ MS' : A[Wk∘Wk,,succ(#1)] }} -> + {{ Γ ⊨ M ≈ M' : ℕ }} -> + {{ Γ ⊨ rec M return A | zero -> MZ | succ -> MS end ≈ rec M' return A' | zero -> MZ' | succ -> MS' end : A[Id,,M] }}. +Proof. + pose proof (@relation_equivalence_pointwise domain). + pose proof (@relation_equivalence_pointwise env). + intros * [env_relΓℕ] [env_relΓ] [env_relΓℕA] []. + destruct_conjs. + pose (env_relΓ0 := env_relΓ). + pose (env_relΓℕ0 := env_relΓℕ). + pose (env_relΓℕA0 := env_relΓℕA). + inversion_by_head (per_ctx_env env_relΓℕA); subst. + inversion_by_head (per_ctx_env env_relΓℕ); subst. + handle_per_ctx_env_irrel. + unshelve eexists_rel_exp; [constructor |]. + intros. + (on_all_hyp: destruct_rel_by_assumption tail_rel0). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ ℕ }}}); subst. + match goal with + | H : per_univ_elem _ _ d{{{ ℕ }}} d{{{ ℕ }}} |- _ => + invert_per_univ_elem H; + apply_relation_equivalence + end. + inversion_by_head (eval_exp {{{ A[Id ,, zero] }}}); subst. + inversion_by_head (eval_sub {{{ Id ,, zero }}}); subst. + destruct_by_head rel_exp. + handle_per_univ_elem_irrel. + match goal with + | HM : {{ ⟦ M ⟧ p ↘ ~?m }}, HM' : {{ ⟦ M' ⟧ p' ↘ ~?m' }} |- _ => + assert {{ Dom p ↦ m ≈ p' ↦ m' ∈ env_relΓℕ }} as Hequiv by (apply_relation_equivalence; eexists; eauto) + end. + apply_relation_equivalence. + (on_all_hyp: fun H => destruct (H _ _ Hequiv) as [? []]). + destruct_by_head rel_typ. + inversion_by_head (eval_exp {{{ Type@i }}}); subst. + match goal with + | H : per_univ_elem _ _ d{{{ 𝕌@?i }}} d{{{ 𝕌@?i }}} |- _ => + invert_per_univ_elem H; + apply_relation_equivalence; + clear_refl_eqs + end. + destruct_by_head rel_exp. + destruct_conjs. + Abort.