Require Import Omega. Require Import Autosubst.Autosubst. Require Import MyTactics. (* TEMPORARY *) (* -------------------------------------------------------------------------- *) (* A more recognizable notation for lifting. *) Notation lift i t := (t.[ren(+i)]). (* -------------------------------------------------------------------------- *) Section Extras. Context A `{Ids A, Rename A, Subst A, SubstLemmas A}. Lemma up_ren: forall xi, ren (upren xi) = up (ren xi). Proof. intros. autosubst. Qed. Lemma upn_ren: forall i xi, ren (iterate upren i xi) = upn i (ren xi). Proof. induction i; intros. { reflexivity. } { rewrite <- fold_up_upn. rewrite <- IHi. asimpl. reflexivity. } Qed. Lemma plus_upn: (* close to [up_liftn] *) forall i sigma, (+i) >>> upn i sigma = sigma >> ren (+i). Proof. induction i; intros. { rewrite iterate_0. autosubst. } { rewrite iterate_S. asimpl. rewrite IHi. autosubst. } Qed. Lemma up_sigma_up_ren: forall t i sigma, t.[up sigma].[up (ren (+i))] = t.[up (ren (+i))].[upn (1 + i) sigma]. Proof. intros. asimpl. rewrite plus_upn. asimpl. reflexivity. Qed. Lemma upn_k_sigma_x: forall k sigma x, x < k -> upn k sigma x = ids x. Proof. induction k; intros; asimpl. { omega. } { destruct x; asimpl. { eauto. } { rewrite IHk by omega. autosubst. } } Qed. Lemma push_substitution_last: forall t v i, t.[v .: ren (+i)] = t.[up (ren (+i))].[v/]. Proof. intros. autosubst. Qed. Lemma push_substitution_last_up_hoist: forall t v i j, t.[up (v .: ren (+i))].[up (ren (+j))] = t.[up (up (ren (+j + i)))].[up (lift j v .: ids)]. Proof. intros. autosubst. Qed. Lemma lift_lift: forall i j t, lift i (lift j t) = lift (i + j) t. Proof. intros. autosubst. Qed. Lemma lift_upn: forall t i sigma, (lift i t).[upn i sigma] = lift i t.[sigma]. Proof. intros. asimpl. erewrite plus_upn. reflexivity. Qed. Lemma lift_up: forall t sigma, (lift 1 t).[up sigma] = lift 1 t.[sigma]. Proof. intros. change up with (upn 1). eapply lift_upn. Qed. Lemma up_sigma_f: forall (sigma : var -> A) (f : A -> A), f (ids 0) = ids 0 -> (forall i t, lift i (f t) = f (lift i t)) -> up (sigma >>> f) = up sigma >>> f. Proof. intros. f_ext. intros [|x]; asimpl; eauto. Qed. Lemma upn_sigma_f: forall (sigma : var -> A) (f : A -> A), f (ids 0) = ids 0 -> (forall i t, lift i (f t) = f (lift i t)) -> forall i, upn i (sigma >>> f) = upn i sigma >>> f. Proof. induction i; intros. { reflexivity. } { do 2 rewrite <- fold_up_upn. rewrite IHi. erewrite up_sigma_f by eauto. reflexivity. } Qed. Lemma upn_theta_sigma_ids: forall theta sigma i, theta >> sigma = ids -> upn i theta >> upn i sigma = ids. Proof. intros theta sigma i Hid. rewrite up_comp_n. rewrite Hid. rewrite up_id_n. reflexivity. Qed. Lemma up_theta_sigma_ids: forall theta sigma, theta >> sigma = ids -> up theta >> up sigma = ids. Proof. change up with (upn 1). eauto using upn_theta_sigma_ids. Qed. Lemma scons_scomp: forall (T : A) Gamma theta, T.[theta] .: (Gamma >> theta) = (T .: Gamma) >> theta. Proof. intros. autosubst. Qed. (* BUG: the two sides of this equation are distinct, yet they are printed identically. *) Goal forall v f, v .: (ids >>> f) = (v .: ids) >>> f. Proof. intros. Fail reflexivity. Abort. End Extras. (* This incantation means that [eauto with autosubst] can use the tactic [autosubst] to prove an equality. *) Hint Extern 1 (_ = _) => autosubst : autosubst. (* This incantation means that [eauto with autosubst] can use the lemmas whose names are listed here. This is useful when an equality involves metavariables, so the tactic [autosubst] fails. *) Hint Resolve scons_scomp : autosubst. (* -------------------------------------------------------------------------- *)