(**************************************************************** Copyright © 2010-2024 Amy Felty This file is part of "Two-Level Hybrid in Coq" This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***************************************************************) (**************************************************************** File: ShapesR.v original: January 2010 updated: March 2014 Apr 2024: Current Coq Version: V8.18.0 Context relation version (R version) of proofs of properties about equality and shapes. ***************************************************************) From HybridSys Require Export Shapes. (**************************************************************** 1. If equal T E then shape T E. ****************************************************************) Section eqsh. (************) (* Contexts *) (************) Inductive avR : list atm -> list atm -> Prop := | nil_av: avR nil nil | cons_av: forall (Phi Psi:list atm) (x y:uexp), proper x -> proper y -> avR Phi Psi -> avR (eq_a x y::Phi) (varE y::varT x::Psi). Hint Resolve nil_av cons_av : hybrid. Lemma memb_av : forall (Phi Psi:list atm) (x y:uexp), avR Phi Psi -> In (eq_a x y) Phi -> (In (varT x) Psi /\ In (varE y) Psi). Proof. intros Phi Psi x y; induction 1; eauto with hybrid. intro h2; simpl in h2; destruct h2 as [h2 | h2]. - injection h2; intros; subst; simpl; auto. - simpl; tauto. Qed. (****************************) (* Main Lemmas and Theorems *) (****************************) Lemma eq_shape : forall (i:nat) (T E:uexp) (Phi Psi:list atm), avR Phi Psi -> seq_ i Phi (atom_ (eq_a T E)) -> seq_ (2*i+2) Psi (atom_ (shape T E)). Proof. intro i. generalize (lt_wf_ind i (fun i:nat => forall (T E:uexp) (Phi Psi:list atm), avR Phi Psi -> seq_ i Phi (atom_ (eq_a T E)) -> seq_ (2*i+2) Psi (atom_ (shape T E)))). intro H'. apply H'; clear H' i; auto. intros i h T E Phi Psi cInv h1. inversion h1; subst; clear h1. - inversion H0; subst; clear H0. (* lam case *) + generalize (eq_lam_inv i0 Phi T0 E0 H3); clear H3; intros [j [h1 h2]]; subst. replace (2*(j+3+1)+2) with (2*j+1+1+1+1+1+1+1+1+1+1); try lia. unfold seq_,atom_; apply s_bc with (All (fun x:uexp => (All (fun y:uexp => (Imp (varT x) (Imp (varE y) (atom_ (shape (T0 x) (E0 y))))))))); auto with hybrid. apply s_all; auto. intros x h1. apply s_all; auto. intros y h3. apply s_imp; auto. apply s_imp; auto. apply seq_mono with (2*j+2); auto; try lia. apply h with (eq_a x y::Phi); eauto with hybrid; try lia. (* app case *) + inversion H3; subst; clear H3. replace (2*(i+1+1)+2) with (2*i+1+1+1+1+1+1); try lia. unfold seq_,atom_; apply s_bc with (Conj (atom_ (shape T1 E1)) (atom_ (shape T2 E2))); auto with hybrid. apply s_and; auto. * apply seq_mono with (2*i+2); auto; try lia. apply h with Phi; try lia; auto. * apply seq_mono with (2*i+2); auto; try lia. apply h with Phi; try lia; auto. (* context case *) - inversion cInv; subst. specialize memb_av with (1:=cInv) (2:=H2); intros [h1 h2]; clear H2. replace (2*i+2) with (2*i+1+1); try lia. unfold seq_,atom_; apply s_bc with (Conj (atom_ (varT T)) (atom_ (varE E))); auto with hybrid. apply s_and; auto. + apply s_init; auto with hybrid. + apply s_init; auto with hybrid. Qed. Lemma eq_shape_cor : forall (T E:uexp), seq0 (atom_ (eq_a T E)) -> seq0 (atom_ (shape T E)). Proof. intros T E [i h1]. generalize nil_av; intro h2. specialize eq_shape with (1:=h2) (2:=h1); intro h. exists (2*i+2); auto. Qed. End eqsh. #[global] Hint Resolve nil_av cons_av : hybrid. (**************************************************************** 2. Theorem: if shape T E and varTOcc T N then varTOcc E N. or equivalently Theorem: if shape T E then all N. varTOcc T N implies varTOcc E N. ****************************************************************) Section bndEq. (************) (* Contexts *) (************) Inductive vR : list atm -> list atm -> list atm -> Prop := | nil_v: vR nil nil nil | cons_v: forall (Phi Psi Psi':list atm) (n:nat) (x:uexp), proper x -> vR Phi Psi Psi' -> vR (varE x::varT (Var n)::Phi) (varT (Var n)::Psi) (varE x::Psi'). Hint Resolve nil_v cons_v : hybrid. Lemma memb_v1 : forall (Phi Psi Psi':list atm), vR Phi Psi Psi' -> forall (a:atm), In a Phi -> (exists n:nat, a=(varT (Var n))) \/ (exists E:uexp, a=(varE E)). Proof. intros Phi Psi Psi'; induction 1; auto. - simpl; intros a h; elim h. - intros a h2; simpl in h2; destruct h2 as [h2 | [h2 | h2]]. + right; exists x; auto. + left; exists n; auto. + auto. Qed. Lemma memb_v2 : forall (Phi Psi Psi':list atm), vR Phi Psi Psi' -> forall (a:atm), In a Psi -> exists n:nat, a=(varT (Var n)). Proof. intros Phi Psi Psi'; induction 1. - simpl; intros a h; elim h. - intros a h2; simpl in h2; destruct h2 as [h2 | h2]. + exists n; auto. + auto. Qed. Lemma memb_v3 : forall (Phi Psi Psi':list atm), vR Phi Psi Psi' -> forall (x:uexp), In (varE x) Phi -> In (varE x) Psi'. Proof. intros Phi Psi Psi'; induction 1; auto. intros y h2; simpl in h2; destruct h2 as [h2 | [h2 | h2]]. - injection h2; intros; subst; simpl; auto. - discriminate h2. - simpl; auto. Qed. (****************************) (* Main Lemmas and Theorems *) (****************************) Lemma bndEq : forall (i N:nat) (T E:uexp) (Phi Psi Psi':list atm), vR Phi Psi Psi' -> seq_ i Phi (atom_ (shape T E)) -> seq_ i Psi (atom_ (varTOcc T N)) -> seq_ i Psi' (atom_ (varEOcc E N)). Proof. intro i. generalize (lt_wf_ind i (fun i:nat => forall (N:nat) (T E:uexp) (Phi Psi Psi':list atm), vR Phi Psi Psi' -> seq_ i Phi (atom_ (shape T E)) -> seq_ i Psi (atom_ (varTOcc T N)) -> seq_ i Psi' (atom_ (varEOcc E N)))). intro H'. apply H'; clear H' i; auto. intros i h N T E Phi Psi Psi' cInv h1 h2. inversion h1; subst; clear h1. - inversion H0; subst; clear H0. (* varT/varE case *) + inversion H3; subst; clear H3. specialize memb_v1 with (1:=cInv); intro cInv1. specialize memb_v2 with (1:=cInv); intro cInv2. specialize memb_v3 with (1:=cInv); intro cInv3. inversion h2; subst; clear h2. * inversion H1; subst; clear H1. -- inversion H4; subst; clear H4. ++ inversion H1; subst; clear H1. ++ specialize cInv1 with (1:=H6). elim cInv1; clear cInv1; intros [x h1]; discriminate h1. -- inversion H4; subst; clear H4. ++ inversion H1; subst; clear H1. ++ specialize cInv1 with (1:=H6). elim cInv1; clear cInv1; intros [x h1]; discriminate h1. -- unfold seq_,atom_; apply s_bc with (atom_ (varE E)); auto with hybrid. inversion H5; subst; clear H5. ++ inversion H1; subst; clear H1. ++ specialize cInv3 with (1:=H6). generalize cInv3; case Psi'. ** simpl; tauto. ** intros a Phi h1. apply s_init; auto with hybrid. * specialize cInv2 with (1:=H2); elim cInv2. intros x h1; discriminate h1. (* lam case *) + specialize shape_lam_inv with (1:=H3); intros [j [h1 h3]]; subst; clear H3. replace (j+4+1) with (j+1+1+1+1+1); try lia. unfold seq_,atom_; apply s_bc with (All (fun x:uexp => (Imp (varE x) (atom_ (varEOcc (E0 x) N))))); auto with hybrid. apply s_all. intros x h1. apply s_imp. inversion h2; subst; clear h2. * inversion H1; subst; clear H1. -- inversion H4; subst; clear H4. specialize H8 with (1:=(proper_Var 0)). inversion H8; subst; clear H8. specialize h3 with (1:=(proper_Var 0)) (2:=h1). assert (i=j+1+1); try lia; subst; clear H. assert (h2: seq_ (j+1+1) (varE x :: varT (Var 0) :: Phi) (atom_ (shape (T0 (Var 0)) (E0 x)))). { apply seq_mono with j; try lia; auto. } apply h with (T (Var 0)) (varE x :: varT (Var 0) :: Phi) (varT (Var 0) :: Psi); auto; try lia. ++ eauto with hybrid. ++ specialize abstr_lbind_simp with (1:=H7) (2:=H2) (3:=H0); intro h4. rewrite -> h4; auto with hybrid. -- inversion H4; subst; clear H4. ++ inversion H1; subst; clear H1. ++ specialize memb_v2 with (1:=cInv); intro cInv2. specialize cInv2 with (1:=H6); elim cInv2. intros y h2; discriminate h2. * specialize memb_v2 with (1:=cInv); intro cInv2. specialize cInv2 with (1:=H3); elim cInv2. intros y h2; discriminate h2. (* app/apply case *) + inversion H3; subst; clear H3. inversion h2; subst; clear h2. * inversion H1; subst; clear H1. -- inversion H3; subst; clear H3. assert (i=i1); try lia; subst; clear H. unfold seq_,atom_; apply s_bc with (Conj (atom_ (varEOcc E1 N1)) (atom_ (varEOcc E2 N2))); auto with hybrid. apply s_and; auto. ++ apply h with T1 Phi Psi; auto; try lia. ++ apply h with T2 Phi Psi; auto; try lia. -- inversion H3; subst; clear H3. ++ inversion H1; subst; clear H1. ++ specialize memb_v2 with (1:=cInv); intro cInv2. specialize cInv2 with (1:=H6); elim cInv2. intros x h1; discriminate h1. * specialize memb_v2 with (1:=cInv); intro cInv2. specialize cInv2 with (1:=H2); elim cInv2. intros x h1; discriminate h1. (* context case *) - specialize memb_v1 with (1:=cInv); intro cInv1. specialize cInv1 with (1:=H2); elim cInv1; intros [x h1]; discriminate h1. Qed. End bndEq.