{-# OPTIONS --safe --without-K #-} module IS4.Term.Properties where open import Relation.Binary.PropositionalEquality using (_≡_ ; refl ; sym ; trans ; cong ; cong₂ ; subst-subst ; module ≡-Reasoning) import Relation.Binary.Reasoning.Setoid as SetoidReasoning open import PEUtil import RUtil open import IS4.Term.Base open import IS4.Term.Conversion open import IS4.Term.Reduction ---------------------- -- Substitution lemmas ---------------------- -- Left context of weakening and applying a substituion -- is the same as the -- Left context of applying and then weakening it lCtxₛ-wkSub-comm : (e : CExt Γ ΓL ΓR) (s : Sub Δ Γ) (w : Δ ⊆ Δ') → lCtxₛ e (wkSub w s) ≡ lCtx (factorExtₛ e s) w lCtxₛ-wkSub-comm nil _s _w = refl lCtxₛ-wkSub-comm (ext e) (s `, _t) w = lCtxₛ-wkSub-comm e s w lCtxₛ-wkSub-comm (ext#- e) (lock s e') w = trans˘ (lCtxₛ-wkSub-comm e s (factorWk e' w)) (lCtxPresTrans (factorExtₛ e _) e' _) -- Right context of weakening and applying a substituion -- is the same as the -- Right context of applying and then weakening it rCtxₛ-wkSub-comm : (e : CExt Γ ΓL ΓR) (s : Sub Δ Γ) (w : Δ ⊆ Δ') → rCtxₛ e (wkSub w s) ≡ rCtx (factorExtₛ e s) w rCtxₛ-wkSub-comm nil _s _w = refl rCtxₛ-wkSub-comm (ext e) (s `, _t) w = rCtxₛ-wkSub-comm e s w rCtxₛ-wkSub-comm (ext#- e) (lock s e') w = trans˘ (cong1 _,,_ (rCtxₛ-wkSub-comm e s (factorWk e' w))) (rCtxPresTrans (factorExtₛ e _) e' _) -- Weakening and factoring a subtitution can be achieved by factoring and then weakening it factorSubₛ-wkSub-comm : (e : CExt Γ ΓL ΓR) (s : Sub Δ Γ) (w : Δ ⊆ Δ') → subst1 Sub (lCtxₛ-wkSub-comm e s w) (factorSubₛ e (wkSub w s)) ≡ wkSub (factorWk (factorExtₛ e s) w) (factorSubₛ e s) factorSubₛ-wkSub-comm nil _s _w = refl factorSubₛ-wkSub-comm (ext e) (s `, _t) w = factorSubₛ-wkSub-comm e s w factorSubₛ-wkSub-comm (ext#- e) (lock s e') w = let open ≡-Reasoning in begin subst1 Sub (trans˘ (lCtxₛ-wkSub-comm e _ _) (lCtxPresTrans _ e' _)) (factorSubₛ e (wkSub (factorWk e' w) s)) -- split `subst _ (trans p q) ...` to `subst _ q (subst _ p ...)` ≡˘⟨ subst-subst (lCtxₛ-wkSub-comm e _ _) ⟩ subst1˘ Sub (lCtxPresTrans _ e' _) (subst1 Sub (lCtxₛ-wkSub-comm e _ _) (factorSubₛ e (wkSub (factorWk e' w) s))) -- rewrite inner subst ≡⟨ cong (subst1 Sub _) (factorSubₛ-wkSub-comm e s (factorWk e' w)) ⟩ subst1˘ Sub (lCtxPresTrans _ e' _) (wkSub (factorWk (factorExtₛ e s) (factorWk e' w)) (factorSubₛ e s)) -- commute subst with application ≡⟨ subst˘-application1′ wkSub (lCtxPresTrans _ e' _) ⟩ wkSub (subst˘ (_ ⊆_) (lCtxPresTrans _ e' _) (factorWk (factorExtₛ e s) (factorWk e' w))) (factorSubₛ e s) -- apply factorWkPresTrans ≡˘⟨ cong1 wkSub (subst-sym (lCtxPresTrans _ e' _) (factorWkPresTrans (factorExtₛ e s) e' w)) ⟩ wkSub (factorWk (extRAssoc (factorExtₛ e s) e') w) (factorSubₛ e s) ∎ lCtxₛ-factorExt-trimSub-assoc : (e : CExt Γ ΓL ΓR) (s : Sub Δ' Δ) (w : Γ ⊆ Δ) → lCtxₛ e (trimSub w s) ≡ lCtxₛ (factorExt e w) s lCtxₛ-factorExt-trimSub-assoc nil s w = refl lCtxₛ-factorExt-trimSub-assoc (ext e) (s `, _) (drop w) = lCtxₛ-factorExt-trimSub-assoc (ext e) s w lCtxₛ-factorExt-trimSub-assoc (ext e) (s `, _) (keep w) = lCtxₛ-factorExt-trimSub-assoc e s w lCtxₛ-factorExt-trimSub-assoc (ext#- e) (s `, t) (drop w) = lCtxₛ-factorExt-trimSub-assoc (ext#- e) s w lCtxₛ-factorExt-trimSub-assoc (ext#- e) (lock s _) (keep# w) = lCtxₛ-factorExt-trimSub-assoc e s w rCtxₛ-factorExt-trimSub-assoc : (e : CExt Γ ΓL ΓR) (s : Sub Δ' Δ) (w : Γ ⊆ Δ) → rCtxₛ e (trimSub w s) ≡ rCtxₛ (factorExt e w) s rCtxₛ-factorExt-trimSub-assoc nil s w = refl rCtxₛ-factorExt-trimSub-assoc (ext e) (s `, t) (drop w) = rCtxₛ-factorExt-trimSub-assoc (ext e) s w rCtxₛ-factorExt-trimSub-assoc (ext e) (s `, t) (keep w) = rCtxₛ-factorExt-trimSub-assoc e s w rCtxₛ-factorExt-trimSub-assoc (ext#- e) (s `, t) (drop w) = rCtxₛ-factorExt-trimSub-assoc (ext#- e) s w rCtxₛ-factorExt-trimSub-assoc (ext#- e) (lock s _) (keep# w) = cong (_,, _) (rCtxₛ-factorExt-trimSub-assoc e s w) factorSubₛ-trimSub-comm : (e : CExt Γ ΓL ΓR) (s : Sub Δ' Δ) (w : Γ ⊆ Δ) → subst1 Sub (lCtxₛ-factorExt-trimSub-assoc e s w) (factorSubₛ e (trimSub w s)) ≡ trimSub (factorWk e w) (factorSubₛ (factorExt e w) s) factorSubₛ-trimSub-comm nil s w = refl factorSubₛ-trimSub-comm (ext e) (s `, _) (drop w) = factorSubₛ-trimSub-comm (ext e) s w factorSubₛ-trimSub-comm (ext e) (s `, _) (keep w) = factorSubₛ-trimSub-comm e s w factorSubₛ-trimSub-comm (ext#- e) (s `, t) (drop w) = factorSubₛ-trimSub-comm (ext#- e) s w factorSubₛ-trimSub-comm (ext#- e) (lock s _) (keep# w) = factorSubₛ-trimSub-comm e s w --------------------------------------------- -- Factorisation of the identity substitution --------------------------------------------- ←#₁rCtx : (e : CExt Γ ΓL ΓR) → Ctx ←#₁rCtx nil = [] ←#₁rCtx (ext {a = a} e) = ←#₁rCtx e ,, rCtx′ (factorExtₛ e idₛ) freshExt[ a ] ←#₁rCtx (ext#- e) = ←#₁rCtx e private ex : {a b c : Ty} → CExt (ΓL `, a `, b # `, c #) ΓL ([] `, a `, b # `, c #) ex {Γ} {a} {b} {c} = ext#- (ext[ c ] (ext#- (ext[ b ] (ext[ a ] nil)))) _ : ←#₁rCtx (ex {ΓL} {c = c}) ≡ [] `, a `, b _ = refl -- Given `e` that ΓL extends Γ, ΓL is a lock-free extension of `lCtxₛ e idₛ`. -- This means that ΓL ⊆ (lCtxₛ e idₛ), and thus applying `factorSubₛ e idₛ` weakens -- a term with variables in `←#₁rCtx e` factorSubₛIdWk : (e : CExt Γ ΓL ΓR) → LFExt (lCtxₛ e idₛ) ΓL (←#₁rCtx e) factorSubₛIdWk nil = nil factorSubₛIdWk {ΓR = ΓR `, a} (ext {a = .a} e) = subst˘ (λ Γ → LFExt Γ _ (←#₁rCtx (ext e))) (lCtxₛ-wkSub-comm e idₛ fresh) (extRAssoc (factorSubₛIdWk e) (factorDropsWk (factorExtₛ e idₛ) freshExt)) factorSubₛIdWk (ext#- e) = factorSubₛIdWk e -- Obs: Deliberately named _Wk instead of _LFExt -------------------- -- Substitution laws -------------------- -- NOTE: these are only the laws that follow directly from the structure of substitutions coh-trimSub-wkVar : (x : Var Γ a) (s : Sub Δ' Δ) (w : Γ ⊆ Δ) → substVar (trimSub w s) x ≡ substVar s (wkVar w x) coh-trimSub-wkVar zero (s `, x) (drop w) = coh-trimSub-wkVar zero s w coh-trimSub-wkVar zero (s `, x) (keep w) = refl coh-trimSub-wkVar (succ x) (s `, x₁) (drop w) = coh-trimSub-wkVar (succ x) s w coh-trimSub-wkVar (succ x) (s `, x₁) (keep w) = coh-trimSub-wkVar x s w -- `trimSub` preserves the identity trimSubPresId : (s : Sub Δ Γ) → trimSub idWk s ≡ s trimSubPresId [] = refl trimSubPresId (s `, t) = cong1 _`,_ (trimSubPresId s) trimSubPresId (lock s e) = cong1 lock (trimSubPresId s) -- naturality of substVar nat-substVar : (v : Var Γ a) (s : Sub Δ Γ) (w : Δ ⊆ Δ') → substVar (wkSub w s) v ≡ wkTm w (substVar s v) nat-substVar zero (s `, t) w = refl nat-substVar (succ v) (s `, t) w = nat-substVar v s w -- naturality of trimSub nat-trimSub : (s : Sub Γ Δ) (w : Δ' ⊆ Δ) (w' : Γ ⊆ Γ') → wkSub w' (trimSub w s) ≡ trimSub w (wkSub w' s) nat-trimSub [] base w' = refl nat-trimSub (s `, t) (drop w) w' = nat-trimSub s w w' nat-trimSub (s `, t) (keep w) w' = cong1 _`,_ (nat-trimSub s w w') nat-trimSub (lock s e) (keep# w) w' = cong1 lock (nat-trimSub s w (factorWk e w')) -- `trimSub` on the identity substitution embeds the weakening trimSubId : (w : Γ ⊆ Δ) → trimSub w idₛ ≡ embWk w trimSubId base = refl trimSubId (drop w) = ˘trans (nat-trimSub idₛ w fresh) (cong (wkSub fresh) (trimSubId w)) trimSubId (keep w) = cong (_`, var zero) (˘trans (nat-trimSub idₛ w fresh) (cong (wkSub fresh) (trimSubId w))) trimSubId (keep# w) = cong1 lock (trimSubId w) --------------------------- -- Hell Of Syntactic Lemmas --------------------------- -- Welcome to the hell of mind-numbing syntactic lemmas. -- No good ever comes from proving these lemmas, but no -- good can happen without proving them. module _ {e : CExt Δ Γ ΓR} {e' : CExt Δ Γ' ΓR'} where cong-unbox≡′′ : (Γ≡Γ' : Γ ≡ Γ') → (t≡t' : subst1 Tm Γ≡Γ' t ≡ t') → unbox t e ≡ unbox t' e' cong-unbox≡′′ Γ≡Γ' t≡t' = idcong₄ unbox Γ≡Γ' (extRUniq′ Γ≡Γ' e e') t≡t' (ExtIsProp _ _) cong-unbox≡ : (t≡t' : t ≡ t') → unbox t e ≡ unbox t' e cong-unbox≡ = cong-unbox≡′′ refl cong-unbox2≡ : unbox t e ≡ unbox t e' cong-unbox2≡ = cong-unbox≡′′ refl refl cong-unbox≡′ : (t≡t' : t ≡ t') → unbox t e ≡ unbox t' e' cong-unbox≡′ = cong-unbox≡′′ refl module _ {e : CExt Δ Γ ΓR} {e' : CExt Δ Γ' ΓR'} where cong-lock≡′′ : (Γ≡Γ' : Γ ≡ Γ') → (s≡s' : subst1 Sub Γ≡Γ' s ≡ s') → lock s e ≡ lock s' e' cong-lock≡′′ Γ≡Γ' s≡s' = idcong₄ lock Γ≡Γ' (extRUniq′ Γ≡Γ' e e') s≡s' (ExtIsProp _ _) cong-lock≡ : (s≡s' : s ≡ s') → lock s e ≡ lock s' e cong-lock≡ = cong-lock≡′′ refl cong-lock2≡ : lock s e ≡ lock s e' cong-lock2≡ = cong-lock≡′′ refl refl cong-lock≡′ : (s≡s' : s ≡ s') → lock s e ≡ lock s' e' cong-lock≡′ = cong-lock≡′′ refl wkTmPresId : (t : Tm Γ a) → wkTm idWk t ≡ t wkTmPresId (var v) = cong var (wkVarPresId v) wkTmPresId (lam t) = cong lam (wkTmPresId t) wkTmPresId (app t u) = cong₂ app (wkTmPresId t) (wkTmPresId u) wkTmPresId (box t) = cong box (wkTmPresId t) wkTmPresId (unbox t e) = let open ≡-Reasoning in begin wkTm idWk (unbox t e) ≡⟨⟩ unbox (wkTm (factorWk e idWk) t) (factorExt e idWk) ≡⟨ cong-unbox≡′′ (lCtxPresId e) (trans (subst-application1′ wkTm (lCtxPresId e)) (cong1 wkTm (factorWkPresId e))) ⟩ unbox (wkTm idWk t) e ≡⟨ cong1 unbox (wkTmPresId t) ⟩ unbox t e ∎ wkSubPresId : (s : Sub Δ Γ) → wkSub idWk s ≡ s wkSubPresId [] = refl wkSubPresId (s `, t) = cong₂ _`,_ (wkSubPresId s) (wkTmPresId t) wkSubPresId (lock s e) = let open ≡-Reasoning in begin wkSub idWk (lock s e) ≡⟨⟩ lock (wkSub (factorWk e idWk) s) (factorExt e idWk) ≡⟨ cong-lock≡′′ (lCtxPresId e) (trans (subst-application1′ wkSub (lCtxPresId e)) (cong1 wkSub (factorWkPresId e))) ⟩ lock (wkSub idWk s) e ≡⟨ cong1 lock (wkSubPresId s) ⟩ lock s e ∎ wkTmPres∙ : (w : Γ ⊆ Γ') (w' : Γ' ⊆ Γ'') (t : Tm Γ a) → wkTm w' (wkTm w t) ≡ wkTm (w ∙ w') t wkTmPres∙ w w' (var v) = cong var (wkVarPres∙ w w' v) wkTmPres∙ w w' (lam t) = cong lam (wkTmPres∙ (keep w) (keep w') t) wkTmPres∙ w w' (app t u) = cong₂ app (wkTmPres∙ w w' t) (wkTmPres∙ w w' u) wkTmPres∙ w w' (box t) = cong box (wkTmPres∙ (keep# w) (keep# w') t) wkTmPres∙ w w' (unbox t e) = let open ≡-Reasoning in begin wkTm w' (wkTm w (unbox t e)) ≡⟨⟩ unbox (wkTm (factorWk (factorExt e w) w') (wkTm (factorWk e w) t)) (factorExt (factorExt e w) w') ≡⟨ cong-unbox≡′ (wkTmPres∙ _ _ t) ⟩ unbox (wkTm (factorWk e w ∙ factorWk (factorExt e w) w') t) (factorExt (factorExt e w) w') ≡˘⟨ cong-unbox≡′′ (lCtxPres∙ e w w') (trans (subst-application1′ wkTm (lCtxPres∙ e w w')) (cong1 wkTm (factorWkPres∙ e w w'))) ⟩ unbox (wkTm (factorWk e (w ∙ w')) t) (factorExt e (w ∙ w')) ≡⟨⟩ wkTm (w ∙ w') (unbox t e) ∎ wkSubPres∙ : (w : Δ ⊆ Δ') (w' : Δ' ⊆ Δ'') (s : Sub Δ Γ) → wkSub w' (wkSub w s) ≡ wkSub (w ∙ w') s wkSubPres∙ _w _w' [] = refl wkSubPres∙ w w' (s `, t) = cong₂ _`,_ (wkSubPres∙ w w' s) (wkTmPres∙ w w' t) wkSubPres∙ w w' (lock s e) = let open ≡-Reasoning in begin wkSub w' (wkSub w (lock s e)) ≡⟨⟩ lock (wkSub (factorWk (factorExt e w) w') (wkSub (factorWk e w) s)) (factorExt (factorExt e w) w') ≡⟨ cong1 lock (wkSubPres∙ _ _ _ ) ⟩ lock (wkSub (factorWk e w ∙ factorWk (factorExt e w) w') s) (factorExt (factorExt e w) w') ≡˘⟨ cong-lock≡′′ (lCtxPres∙ e w w') (trans (subst-application1′ wkSub (lCtxPres∙ e w w')) (cong1 wkSub (factorWkPres∙ e w w'))) ⟩ lock (wkSub (factorWk e (w ∙ w')) s) (factorExt e (w ∙ w')) ≡⟨⟩ wkSub (w ∙ w') (lock s e) ∎ private wkSubFreshLemma : {s : Sub Δ Γ} {w : Δ ⊆ Δ'} → wkSub fresh[ a ] (wkSub w s) ≡ wkSub (keep w) (dropₛ s) wkSubFreshLemma {s = s} {w} = trans (wkSubPres∙ w fresh s) (trans˘ (cong1 wkSub (cong drop (rightIdWk _)) ) (trans (wkSubPres∙ _ _ _) (cong1 wkSub (cong drop (leftIdWk _))))) nat-substTm : (t : Tm Γ a) (s : Sub Δ Γ) (w : Δ ⊆ Δ') → substTm (wkSub w s) t ≡ wkTm w (substTm s t) nat-substTm (var v) s w = nat-substVar v s w nat-substTm (lam t) s w = cong lam (trans (cong (λ s → substTm (s `, var zero) t) wkSubFreshLemma) (nat-substTm t (keepₛ s) (keep w))) nat-substTm (app t u) s w = cong₂ app (nat-substTm t s w) (nat-substTm u s w) nat-substTm (box t) s w = cong box (nat-substTm t (lock s (ext#- nil)) (keep# w)) nat-substTm (unbox t e) s w = let open ≡-Reasoning in begin substTm (wkSub w s) (unbox t e) ≡⟨⟩ unbox (substTm (factorSubₛ e (wkSub w s)) t) (factorExtₛ e (wkSub w s)) ≡⟨ cong-unbox≡′′ (lCtxₛ-wkSub-comm e s w) (trans (subst-application1′ substTm {z = t} (lCtxₛ-wkSub-comm e s w)) (cong1 substTm {y = t} (factorSubₛ-wkSub-comm e s w))) ⟩ unbox (substTm (wkSub (factorWk (factorExtₛ e s) w) (factorSubₛ e s)) t) (factorExt (factorExtₛ e s) w) ≡⟨ cong-unbox≡ (nat-substTm t _ _) ⟩ unbox (wkTm (factorWk (factorExtₛ e s) w) (substTm (factorSubₛ e s) t)) (factorExt (factorExtₛ e s) w) ≡⟨⟩ wkTm w (substTm s (unbox t e)) ∎ coh-wkSub-∙ₛ : {Δ'' : Ctx} (s : Sub Δ Γ) (s' : Sub Δ' Δ) (w : Δ' ⊆ Δ'') → wkSub w (s ∙ₛ s') ≡ s ∙ₛ wkSub w s' coh-wkSub-∙ₛ [] _s' _w = refl coh-wkSub-∙ₛ (s `, t) s' w = cong₂ _`,_ (coh-wkSub-∙ₛ s s' w) (sym (nat-substTm t s' w)) coh-wkSub-∙ₛ (lock s e) s' w = let open ≡-Reasoning in begin wkSub w (lock s e ∙ₛ s') ≡⟨⟩ lock (wkSub (factorWk (factorExtₛ e s') w) (s ∙ₛ factorSubₛ e s')) (factorExt (factorExtₛ e s') w) -- apply IH ≡⟨ cong1 lock (coh-wkSub-∙ₛ _ _ _) ⟩ lock (s ∙ₛ wkSub (factorWk (factorExtₛ e s') w) (factorSubₛ e s')) (factorExt (factorExtₛ e s') w) -- applying factoring equalities ≡˘⟨ cong-lock≡′′ (lCtxₛ-wkSub-comm e s' w) (trans (subst-application′ (s ∙ₛ_) (lCtxₛ-wkSub-comm e s' w)) (cong (s ∙ₛ_) (factorSubₛ-wkSub-comm e s' w))) ⟩ lock (s ∙ₛ factorSubₛ e (wkSub w s')) (factorExtₛ e (wkSub w s')) ≡⟨⟩ lock s e ∙ₛ wkSub w s' ∎ coh-trimSub-wkTm : (t : Tm Γ a) (s : Sub Δ' Δ) (w : Γ ⊆ Δ) → substTm (trimSub w s) t ≡ substTm s (wkTm w t) coh-trimSub-wkTm (var v) s w = coh-trimSub-wkVar v s w coh-trimSub-wkTm (lam t) s w = cong lam (trans (cong (λ p → substTm (p `, var zero) t) (nat-trimSub s w fresh)) (coh-trimSub-wkTm t (keepₛ s) (keep w))) coh-trimSub-wkTm (app t u) s w = cong₂ app (coh-trimSub-wkTm t s w) (coh-trimSub-wkTm u s w) coh-trimSub-wkTm (box t) s w = cong box (coh-trimSub-wkTm t (lock s (ext#- nil)) (keep# w)) coh-trimSub-wkTm (unbox t e) s w = let open ≡-Reasoning in begin substTm (trimSub w s) (unbox t e) ≡⟨⟩ unbox (substTm (factorSubₛ e (trimSub w s)) t) (factorExtₛ e (trimSub w s)) -- apply factoring equalities ≡⟨ cong-unbox≡′′ (lCtxₛ-factorExt-trimSub-assoc e s w) (trans (subst-application1′ substTm {z = t} (lCtxₛ-factorExt-trimSub-assoc e s w)) (cong1 substTm {y = t} (factorSubₛ-trimSub-comm e s w))) ⟩ unbox (substTm (trimSub (factorWk e w) (factorSubₛ (factorExt e w) s)) t) (factorExtₛ (factorExt e w) s) -- aplpy IH ≡⟨ cong1 unbox (coh-trimSub-wkTm t _ _) ⟩ unbox (substTm (factorSubₛ (factorExt e w) s) (wkTm (factorWk e w) t)) (factorExtₛ (factorExt e w) s) ≡⟨⟩ substTm s (wkTm w (unbox t e)) ∎ coh-trimSub-wkSub : {Δ₁ : Ctx} (s : Sub Δ Γ) (s' : Sub Δ₁ Δ') (w : Δ ⊆ Δ') → s ∙ₛ trimSub w s' ≡ wkSub w s ∙ₛ s' coh-trimSub-wkSub [] _s' _w = refl coh-trimSub-wkSub (s `, t) s' w = cong₂ _`,_ (coh-trimSub-wkSub s s' w) (coh-trimSub-wkTm t s' w) coh-trimSub-wkSub (lock s e) s' w = let open ≡-Reasoning in begin lock s e ∙ₛ trimSub w s' ≡⟨⟩ lock (s ∙ₛ factorSubₛ e (trimSub w s')) (factorExtₛ e (trimSub w s')) -- apply factoring equalities ≡⟨ cong-lock≡′′ (lCtxₛ-factorExt-trimSub-assoc e s' w) (trans (subst-application′ (s ∙ₛ_) (lCtxₛ-factorExt-trimSub-assoc e s' w)) (cong (s ∙ₛ_) (factorSubₛ-trimSub-comm e s' w))) ⟩ lock (s ∙ₛ trimSub (factorWk e w) (factorSubₛ (factorExt e w) s')) (factorExtₛ (factorExt e w) s') -- apply IH ≡⟨ cong1 lock (coh-trimSub-wkSub _ _ _) ⟩ lock (wkSub (factorWk e w) s ∙ₛ factorSubₛ (factorExt e w) s') (factorExtₛ (factorExt e w) s') ≡⟨⟩ wkSub w (lock s e) ∙ₛ s' ∎ lCtxₛPresTrans : ∀ {ΓLL ΓLR : Ctx} (e : CExt ΓL ΓLL ΓLR) (e' : CExt Γ ΓL ΓR) (s : Sub Δ Γ) → lCtxₛ e (factorSubₛ e' s) ≡ lCtxₛ (extRAssoc e e') s lCtxₛPresTrans _e nil _s = refl lCtxₛPresTrans e (ext e') (s `, _t) = lCtxₛPresTrans e e' s lCtxₛPresTrans e (ext#- e') (lock s _e'') = lCtxₛPresTrans e e' s rCtxₛPresTrans : ∀ {ΓLL ΓLR : Ctx} (e : CExt ΓL ΓLL ΓLR) (e' : CExt Γ ΓL ΓR) (s : Sub Δ Γ) → rCtxₛ e (factorSubₛ e' s) ,, rCtxₛ e' s ≡ rCtxₛ (extRAssoc e e') s rCtxₛPresTrans _e nil _s = refl rCtxₛPresTrans e (ext e') (s `, _t) = rCtxₛPresTrans e e' s rCtxₛPresTrans e (ext#- e') (lock {ΔR = ΔR} s _e'') = ˘trans (,,-assoc {ΓR = ΔR}) (cong (_,, ΔR) (rCtxₛPresTrans e e' s)) lCtxₛPres∙ₛ : (e : CExt Γ ΓL ΓR) (s : Sub Γ' Γ) (s' : Sub Δ Γ') → lCtxₛ e (s ∙ₛ s') ≡ lCtxₛ (factorExtₛ e s) s' lCtxₛPres∙ₛ nil _s _s' = refl lCtxₛPres∙ₛ (ext e) (s `, _t) s' = lCtxₛPres∙ₛ e s s' lCtxₛPres∙ₛ (ext#- e) (lock s e') s' = trans (lCtxₛPres∙ₛ e _ _) (lCtxₛPresTrans _ e' _) rCtxₛPres∙ₛ : (e : CExt Γ ΓL ΓR) (s : Sub Γ' Γ) (s' : Sub Δ Γ') → rCtxₛ e (s ∙ₛ s') ≡ rCtxₛ (factorExtₛ e s) s' rCtxₛPres∙ₛ nil _s _s' = refl rCtxₛPres∙ₛ (ext e) (s `, _t) s' = rCtxₛPres∙ₛ e s s' rCtxₛPres∙ₛ (ext#- e) (lock s e') s' = trans (cong (_,, _) (rCtxₛPres∙ₛ e _ _)) (rCtxₛPresTrans _ e' _) factorSubPresTrans : ∀ {ΓLL ΓLR : Ctx} (e : CExt ΓL ΓLL ΓLR) (e' : CExt Γ ΓL ΓR) (s : Sub Δ Γ) → subst1 Sub (lCtxₛPresTrans e e' s) (factorSubₛ e (factorSubₛ e' s)) ≡ factorSubₛ (extRAssoc e e') s factorSubPresTrans _e nil _s = refl factorSubPresTrans e (ext e') (s `, _t) = factorSubPresTrans e e' s factorSubPresTrans e (ext#- e') (lock s _e'') = factorSubPresTrans e e' s factorSubPres∙ₛ : (e : CExt Γ ΓL ΓR) (s : Sub Γ' Γ) (s' : Sub Δ Γ') → subst1 Sub (lCtxₛPres∙ₛ e s s') (factorSubₛ e (s ∙ₛ s')) ≡ factorSubₛ e s ∙ₛ factorSubₛ (factorExtₛ e s) s' factorSubPres∙ₛ nil _s _s' = refl factorSubPres∙ₛ (ext e) (s `, _t) s' = factorSubPres∙ₛ e s s' factorSubPres∙ₛ (ext#- e) (lock s e') s' = let open ≡-Reasoning in begin subst1 Sub (lCtxₛPres∙ₛ (ext#- e) (lock s e') s') (factorSubₛ (ext#- e) (lock s e' ∙ₛ s')) ≡⟨⟩ subst1 Sub (trans (lCtxₛPres∙ₛ e s (factorSubₛ e' s')) (lCtxₛPresTrans (factorExtₛ e s) e' s')) (factorSubₛ e (s ∙ₛ factorSubₛ e' s')) -- split `subst _ (trans p q) ...` to `subst _ q (subst _ p ...)` ≡˘⟨ subst-subst (lCtxₛPres∙ₛ e s (factorSubₛ e' s')) ⟩ subst1 Sub (lCtxₛPresTrans (factorExtₛ e s) e' s') (subst1 Sub (lCtxₛPres∙ₛ e s (factorSubₛ e' s')) (factorSubₛ e (s ∙ₛ factorSubₛ e' s'))) -- rewrite (remove) inner subst with IH ≡⟨ cong (subst1 Sub _) (factorSubPres∙ₛ e s (factorSubₛ e' s')) ⟩ subst1 Sub (lCtxₛPresTrans (factorExtₛ e s) e' s') (factorSubₛ e s ∙ₛ factorSubₛ (factorExtₛ e s) (factorSubₛ e' s')) -- push subst inside application of (_ ∙ₛ_) ≡⟨ subst-application′ (factorSubₛ e s ∙ₛ_) (lCtxₛPresTrans (factorExtₛ e s) e' s') ⟩ factorSubₛ e s ∙ₛ subst1 Sub (lCtxₛPresTrans (factorExtₛ e s) e' s') (factorSubₛ (factorExtₛ e s) (factorSubₛ e' s')) -- apply factorSubPresTrans ≡⟨ cong (_ ∙ₛ_) (factorSubPresTrans (factorExtₛ e s) e' s') ⟩ factorSubₛ e s ∙ₛ factorSubₛ (extRAssoc (factorExtₛ e s) e') s' ≡⟨⟩ factorSubₛ (ext#- e) (lock s e') ∙ₛ factorSubₛ (factorExtₛ (ext#- e) (lock s e')) s' ∎ substVarPresId : (x : Var Γ a) → substVar idₛ x ≡ var x substVarPresId zero = refl substVarPresId (succ x) = trans (nat-substVar x idₛ fresh) (trans (cong (wkTm fresh) (substVarPresId x)) (cong var (wkIncr x))) -- parallel substitution (substVar) preserves substitution composition substVarPres∙ : (s : Sub Γ' Γ) (s' : Sub Δ Γ') (x : Var Γ a) → substTm s' (substVar s x) ≡ substVar (s ∙ₛ s') x substVarPres∙ (s `, x) s' zero = refl substVarPres∙ (s `, x) s' (succ x₁) = substVarPres∙ s s' x₁ private dropKeepLemma : (s' : Sub Δ' Δ) (s : Sub Γ Δ') → dropₛ (s' ∙ₛ s) ≡ dropₛ {a = a} s' ∙ₛ keepₛ s dropKeepLemma s' s = trans (coh-wkSub-∙ₛ s' s fresh) (˘trans (cong (s' ∙ₛ_) (trimSubPresId (dropₛ s))) (coh-trimSub-wkSub s' (keepₛ s) fresh)) substTmPres∙ : (s : Sub Γ' Γ) (s' : Sub Δ Γ') (t : Tm Γ a) → substTm s' (substTm s t) ≡ substTm (s ∙ₛ s') t substTmPres∙ s s' (var v) = substVarPres∙ s s' v substTmPres∙ s s' (lam t) = cong lam (trans˘ (substTmPres∙ (keepₛ s) (keepₛ s') t) (cong (λ s → substTm (s `, var zero) t) (dropKeepLemma s s'))) substTmPres∙ s s' (app t u) = cong₂ app (substTmPres∙ s s' t) (substTmPres∙ s s' u) substTmPres∙ s s' (box t) = cong box (substTmPres∙ (keep#ₛ s) (keep#ₛ s') t) substTmPres∙ s s' (unbox t e) = let open ≡-Reasoning in begin substTm s' (substTm s (unbox t e)) ≡⟨⟩ unbox (substTm (factorSubₛ (factorExtₛ e s) s') (substTm (factorSubₛ e s) t)) (factorExtₛ (factorExtₛ e s) s') -- apply IH ≡⟨ cong1 unbox (substTmPres∙ _ _ t) ⟩ unbox (substTm (factorSubₛ e s ∙ₛ factorSubₛ (factorExtₛ e s) s') t) (factorExtₛ (factorExtₛ e s) s') -- apply factoring equalities ≡˘⟨ cong-unbox≡′′ (lCtxₛPres∙ₛ e s s') (trans (subst-application1′ substTm {z = t} (lCtxₛPres∙ₛ e s s')) (cong1 substTm {y = t} (factorSubPres∙ₛ e s s'))) ⟩ unbox (substTm (factorSubₛ e (s ∙ₛ s')) t) (factorExtₛ e (s ∙ₛ s')) ≡⟨⟩ substTm (s ∙ₛ s') (unbox t e) ∎ assocSub : ∀ (s : Sub Δ Γ) (s' : Sub Θ Δ) (s'' : Sub Ξ Θ) → (s ∙ₛ s') ∙ₛ s'' ≡ s ∙ₛ (s' ∙ₛ s'') assocSub [] _s' _s'' = refl assocSub (s `, t) s' s'' = cong₂ _`,_ (assocSub s s' s'') (substTmPres∙ s' s'' t) assocSub (lock s e) s' s'' = let open ≡-Reasoning in begin (lock s e ∙ₛ s') ∙ₛ s'' ≡⟨⟩ lock ((s ∙ₛ factorSubₛ e s') ∙ₛ factorSubₛ (factorExtₛ e s') s'') (factorExtₛ (factorExtₛ e s') s'') -- apply IH ≡⟨ cong1 lock (assocSub _ _ _) ⟩ lock (s ∙ₛ factorSubₛ e s' ∙ₛ factorSubₛ (factorExtₛ e s') s'') (factorExtₛ (factorExtₛ e s') s'') -- apply factoring equalities ≡˘⟨ cong-lock≡′′ (lCtxₛPres∙ₛ e s' s'') (trans (subst-application′ (s ∙ₛ_) (lCtxₛPres∙ₛ e s' s'')) (cong (s ∙ₛ_) (factorSubPres∙ₛ e _ _ ))) ⟩ lock (s ∙ₛ factorSubₛ e (s' ∙ₛ s'')) (factorExtₛ e (s' ∙ₛ s'')) ≡⟨⟩ lock s e ∙ₛ (s' ∙ₛ s'') ∎ leftIdSub : (s : Sub Γ Γ') → idₛ ∙ₛ s ≡ s leftIdSub [] = refl leftIdSub (s `, t) = let open ≡-Reasoning in begin idₛ ∙ₛ (s `, t) ≡⟨⟩ wkSub fresh idₛ ∙ₛ (s `, t) `, t ≡˘⟨ cong (_`, _) (coh-trimSub-wkSub idₛ (s `, t) fresh) ⟩ idₛ ∙ₛ trimSub fresh (s `, t) `, t ≡⟨ cong (_`, _) (trans (leftIdSub _) (trimSubPresId _)) ⟩ (s `, t) ∎ leftIdSub (lock s e) = let open ≡-Reasoning in begin lock (idₛ ∙ₛ s) (extRAssoc nil e) ≡⟨ cong-lock≡′ (leftIdSub s) ⟩ lock s e ∎ wkSubId : (w : Γ ⊆ Δ) → wkSub w idₛ ≡ embWk w private -- just a helper to reduce redundancy, nothing too interesting auxLemma : (w : Γ ⊆ Δ) → wkSub (drop[ a ] (w ∙ idWk)) idₛ ≡ dropₛ (embWk w) auxLemma w = ˘trans (wkSubPres∙ w fresh idₛ) (cong (wkSub fresh) (wkSubId w)) wkSubId base = refl wkSubId (drop w) = ˘trans (cong (λ w' → wkSub (drop w') idₛ) (rightIdWk w)) (auxLemma w) wkSubId (keep w) = cong (_`, var zero) (trans (wkSubPres∙ fresh (keep w) idₛ) (trans (cong1 wkSub (cong drop (trans˘ (leftIdWk _) (rightIdWk _)))) (auxLemma w))) wkSubId (keep# w) = cong1 lock (wkSubId w) -- Outcast lemmas keepFreshLemma : {w : Γ ⊆ Γ'} {t : Tm Γ a} → wkTm fresh[ b ] (wkTm w t) ≡ wkTm (keep w) (wkTm fresh t) keepFreshLemma = trans˘ (wkTmPres∙ _ _ _) (trans (wkTmPres∙ _ _ _) (cong1 wkTm (cong drop (trans˘ (leftIdWk _) (rightIdWk _))))) sliceCompLemma : (w : Γ ⊆ Δ) (e : LFExt Γ (ΓL #) ΓR) (t : Tm (ΓL #) a) → wkTm (LFExtToWk (wkLFExt e w)) (wkTm (keep# (sliceLeft e w)) t) ≡ wkTm w (wkTm (LFExtToWk e) t) sliceCompLemma w e t = trans˘ (wkTmPres∙ _ _ _) (trans (wkTmPres∙ _ _ _) (cong1 wkTm (slicingLemma w e))) beta-wk-lemma : (w : Γ ⊆ Δ) (u : Tm Γ a) (t : Tm (Γ `, a) b) → substTm (idₛ `, wkTm w u) (wkTm (keep w) t) ≡ wkTm w (substTm (idₛ `, u) t) beta-wk-lemma w u t = ˘trans (coh-trimSub-wkTm t _ (keep w)) (trans (cong (λ p → substTm (p `, wkTm w u) t) (trans˘ (trimSubId w) (wkSubId w))) (nat-substTm t _ _)) -- factorising the identity substituion yields a weakening that only drops factorSubₛIdWkIsFactorSubₛId : (e : CExt Γ ΓL ΓR) → factorSubₛ e idₛ ≡ embWk (LFExtToWk (factorSubₛIdWk e)) factorSubₛIdWkIsFactorSubₛId nil = refl factorSubₛIdWkIsFactorSubₛId (ext#- e) = factorSubₛIdWkIsFactorSubₛId e factorSubₛIdWkIsFactorSubₛId (ext {a = a} e) = let open ≡-Reasoning in begin factorSubₛ e (wkSub fresh idₛ) -- apply `factorSubₛ-wkSub-comm` ≡⟨ subst-sym (lCtxₛ-wkSub-comm e idₛ fresh) (factorSubₛ-wkSub-comm e idₛ fresh) ⟩ subst1˘ Sub (lCtxₛ-wkSub-comm e idₛ fresh) (wkSub (factorWk (factorExtₛ e idₛ) fresh) (factorSubₛ e idₛ)) -- apply IH ≡⟨ cong (λ z → subst1˘ Sub (lCtxₛ-wkSub-comm e idₛ fresh) (wkSub (factorWk (factorExtₛ e idₛ) fresh) z)) (factorSubₛIdWkIsFactorSubₛId e) ⟩ subst1˘ Sub (lCtxₛ-wkSub-comm e idₛ fresh) (wkSub (factorWk (factorExtₛ e idₛ) fresh) (embWk (LFExtToWk (factorSubₛIdWk e)))) -- apply `substCrunch` which crunches substitution with substitution and weakening equalities ≡⟨ cong (subst1˘ Sub (lCtxₛ-wkSub-comm e idₛ fresh)) substCrunch ⟩ subst1˘ Sub (lCtxₛ-wkSub-comm e idₛ fresh) (embWk (LFExtToWk (extRAssoc (factorSubₛIdWk e) (factorDropsWk (factorExtₛ e idₛ) freshExt)))) -- pull out subst ≡⟨ subst˘-application′ (λ z → embWk (LFExtToWk z)) (lCtxₛ-wkSub-comm e idₛ fresh) ⟩ embWk (LFExtToWk (subst˘ (λ Γ → LFExt Γ _ (←#₁rCtx e ,, rCtx′ (factorExtₛ e idₛ) freshExt)) (lCtxₛ-wkSub-comm e idₛ fresh) (extRAssoc (factorSubₛIdWk e) (factorDropsWk (factorExtₛ e idₛ) freshExt)))) ≡⟨⟩ embWk (LFExtToWk (factorSubₛIdWk (ext e))) ∎ where -- coh-wkSub-embwk : (w : Γ' ⊆ Γ'') (w' : Γ ⊆ Γ') → wkSub w (embWk w') ≡ embWk (w' ∙ w) coh-wkSub-embwk w w' = let open ≡-Reasoning in begin wkSub w (embWk w') ≡˘⟨ cong (wkSub w) (wkSubId _) ⟩ wkSub w (wkSub w' idₛ) ≡⟨ wkSubPres∙ _ _ _ ⟩ wkSub (w' ∙ w) idₛ ≡⟨ wkSubId _ ⟩ embWk (w' ∙ w) ∎ -- substCrunch : wkSub (factorWk (factorExtₛ e idₛ) fresh[ a ]) (embWk (LFExtToWk (factorSubₛIdWk e))) ≡ embWk (LFExtToWk (extRAssoc (factorSubₛIdWk e) (factorDropsWk (factorExtₛ e idₛ) freshExt))) substCrunch = let open ≡-Reasoning in begin wkSub (factorWk (factorExtₛ e idₛ) fresh[ a ]) (embWk (LFExtToWk (factorSubₛIdWk e))) ≡⟨ coh-wkSub-embwk (factorWk (factorExtₛ e idₛ) fresh[ a ]) (LFExtToWk (factorSubₛIdWk e)) ⟩ embWk (LFExtToWk (factorSubₛIdWk e) ∙ factorWk (factorExtₛ e idₛ) fresh) ≡˘⟨ cong (λ x → embWk (LFExtToWk (factorSubₛIdWk e) ∙ x)) (factorDropsWkIsfactorWk (factorExtₛ e idₛ) freshExt) ⟩ embWk (LFExtToWk (factorSubₛIdWk e) ∙ LFExtToWk (factorDropsWk (factorExtₛ e idₛ) freshExt)) ≡˘⟨ cong embWk (LFExtToWkPresTrans (factorSubₛIdWk e) (factorDropsWk (factorExtₛ e idₛ) freshExt)) ⟩ embWk (LFExtToWk (extRAssoc (factorSubₛIdWk e) (factorDropsWk (factorExtₛ e idₛ) freshExt))) ∎ ----------------------------------- --- Reduction and conversion lemmas ----------------------------------- wkTmPres⟶ : (w : Γ ⊆ Γ') → t ⟶ t' → wkTm w t ⟶ wkTm w t' wkTmPres⟶ w (red-fun t u) = step-≡ (red-fun _ _) (beta-wk-lemma w u t) wkTmPres⟶ w (exp-fun _) = step-≡ (exp-fun _) (cong lam (cong1 app keepFreshLemma)) wkTmPres⟶ w (red-box t e) = step-≡ (red-box _ _) (trans (˘trans (coh-trimSub-wkTm t _ _) (cong (λ s → substTm (lock s (factorExt e w)) t) (trans˘ (trimSubId (factorWk e w)) (wkSubId _)))) (nat-substTm t _ _)) wkTmPres⟶ w (exp-box _) = exp-box _ wkTmPres⟶ w (cong-lam r) = cong-lam (wkTmPres⟶ (keep w) r) wkTmPres⟶ w (cong-box r) = cong-box (wkTmPres⟶ (keep# w) r) wkTmPres⟶ w (cong-unbox {e = e} r) = cong-unbox (wkTmPres⟶ (factorWk e w ) r) wkTmPres⟶ w (cong-app1 r) = cong-app1 (wkTmPres⟶ w r) wkTmPres⟶ w (cong-app2 r) = cong-app2 (wkTmPres⟶ w r) wkTmPres⟶ w (shift-unbox t w' e) = ≡-step-≡ (let open ≡-Reasoning in begin wkTm w (unbox t (extRAssoc (upLFExt w') e)) ≡⟨⟩ unbox (wkTm (factorWk (extRAssoc (upLFExt w') e) w) t) (factorExt (extRAssoc (upLFExt w') e) w) -- factorisation preserves transitivity ≡⟨ cong-unbox≡′′ (lCtxPresTrans (upLFExt w') e w) (trans (subst-application1′ wkTm (lCtxPresTrans (upLFExt w') e w)) (cong1 wkTm (factorWkPresTrans (upLFExt w') e w))) ⟩ unbox (wkTm (factorWk (upLFExt w') (factorWk e w)) t) (extRAssoc (factorExt (upLFExt w') (factorWk e w)) (factorExt e w)) -- apply equalities for absorption of upLFExt ≡˘⟨ cong-unbox≡′′ (lCtxAbsorbsUpLFExt w' (factorWk e w)) (trans (subst-application1′ wkTm (lCtxAbsorbsUpLFExt w' (factorWk e w))) (cong1 wkTm (factorWkAbsorbsUpLFExt w' (factorWk e w)))) ⟩ unbox (wkTm (factorWk w' (factorWk e w)) t) (extRAssoc (upLFExt (factorExt w' (factorWk e w))) (factorExt e w)) ∎) (shift-unbox _ _ _) (let open ≡-Reasoning in begin unbox (wkTm (LFExtToWk (factorExt w' (factorWk e w))) (wkTm (factorWk w' (factorWk e w)) t)) (factorExt e w) -- wkTm preserves composition ≡⟨ cong1 unbox (wkTmPres∙ _ _ _) ⟩ unbox (wkTm (factorWk w' (factorWk e w) ∙ LFExtToWk (factorExt w' (factorWk e w))) t) (factorExt e w) -- apply factorisationLemma ≡˘⟨ cong1 unbox (cong1 wkTm (factorisationLemma w' _)) ⟩ unbox (wkTm (LFExtToWk w' ∙ factorWk e w) t) (factorExt e w) -- wkTm preserves composition ≡˘⟨ cong1 unbox (wkTmPres∙ _ _ _) ⟩ unbox (wkTm (factorWk e w) (wkTm (LFExtToWk w') t)) (factorExt e w) ≡⟨⟩ wkTm w (unbox (wkTm (LFExtToWk w') t) e) ∎) wkTmPres≈ : (w : Γ ⊆ Γ') → t ≈ t' → wkTm w t ≈ wkTm w t' wkTmPres≈ w = cong-⟶-to-cong-≈ (wkTmPres⟶ w) wkSubPres⟶ : (w : Δ ⊆ Δ') → σ ⟶ₛ σ' → wkSub w σ ⟶ₛ wkSub w σ' wkSubPres⟶ w (cong-`,⟶ₛ1 r) = cong-`,⟶ₛ1 (wkSubPres⟶ w r) wkSubPres⟶ w (cong-`,⟶ₛ2 r) = cong-`,⟶ₛ2 (wkTmPres≈ w r) wkSubPres⟶ w (cong-lock⟶ₛ r) = cong-lock⟶ₛ (wkSubPres⟶ _ r) wkSubPres⟶ w (shift-lock⟶ₛ {s = s} w' {e}) = RUtil.≡-step-≡ _⟶ₛ_ (let open ≡-Reasoning in begin wkSub w (lock s (extRAssoc (upLFExt w') e)) ≡⟨⟩ lock (wkSub (factorWk (extRAssoc (upLFExt w') e) w) s) (factorExt (extRAssoc (upLFExt w') e) w) -- factorisation preserves transitivity ≡⟨ cong-lock≡′′ (lCtxPresTrans (upLFExt w') e w) (trans (subst-application1′ wkSub (lCtxPresTrans (upLFExt w') e w)) (cong1 wkSub (factorWkPresTrans (upLFExt w') e w))) ⟩ lock (wkSub (factorWk (upLFExt w') (factorWk e w)) s) (extRAssoc (factorExt (upLFExt w') (factorWk e w)) (factorExt e w)) -- apply equalities for absorption of upLFExt ≡˘⟨ cong-lock≡′′ (lCtxAbsorbsUpLFExt w' (factorWk e w)) (trans (subst-application1′ wkSub (lCtxAbsorbsUpLFExt w' (factorWk e w))) (cong1 wkSub (factorWkAbsorbsUpLFExt w' (factorWk e w)))) ⟩ lock (wkSub (factorWk w' (factorWk e w)) s) (extRAssoc (upLFExt (factorExt w' (factorWk e w))) (factorExt e w)) ∎) (shift-lock⟶ₛ _) (let open ≡-Reasoning in begin lock (wkSub (LFExtToWk (factorExt w' (factorWk e w))) (wkSub (factorWk w' (factorWk e w)) s)) (factorExt e w) -- wkSub preserves composition ≡⟨ cong1 lock (wkSubPres∙ _ _ _) ⟩ lock (wkSub (factorWk w' (factorWk e w) ∙ LFExtToWk (factorExt w' (factorWk e w))) s) (factorExt e w) -- apply factorisation lemma ≡˘⟨ cong1 lock (cong1 wkSub (factorisationLemma w' _)) ⟩ lock (wkSub (LFExtToWk w' ∙ factorWk e w) s) (factorExt e w) -- wkSub preserves composition ≡˘⟨ cong1 lock (wkSubPres∙ _ _ _) ⟩ lock (wkSub (factorWk e w) (wkSub (LFExtToWk w') s)) (factorExt e w) ≡⟨⟩ wkSub w (lock (wkSub (LFExtToWk w') s) e) ∎) wkSubPres≈ : (w : Δ ⊆ Δ') → σ ≈ₛ σ' → wkSub w σ ≈ₛ wkSub w σ' wkSubPres≈ w = cong-⟶ₛ-to-cong-≈ₛ (wkSubPres⟶ w) substTmPresId : (t : Tm Γ a) → t ≈ substTm idₛ t substTmPresId (var x) = ≈-reflexive˘ (substVarPresId x) substTmPresId (lam t) = cong-lam≈ (substTmPresId t) substTmPresId (app t u) = cong-app≈ (substTmPresId t) (substTmPresId u) substTmPresId (box t) = cong-box≈ (substTmPresId t) substTmPresId (unbox t e) = fact-unbox≈ t e where -- coh-wkTm-substTm : (t : Tm Γ a) (w : Γ ⊆ Γ') → wkTm w t ≈ substTm (embWk w) t coh-wkTm-substTm {a = a} {Γ' = Γ'} t w = begin wkTm w t -- apply IH ≈⟨ wkTmPres≈ w (substTmPresId t) ⟩ wkTm w (substTm idₛ t) -- apply naturality of substTm ≡˘⟨ nat-substTm t idₛ w ⟩ substTm (wkSub w idₛ) t -- weakening id subst is same as embedding the weakening into a subst ≡⟨ cong1 substTm {y = t} (wkSubId w) ⟩ substTm (embWk w) t ∎ where open SetoidReasoning (Tm-setoid Γ' a) -- fact-unbox≈ : (t : Tm ΓL (□ a)) (e : CExt Γ ΓL ΓR) → unbox t e ≈ unbox (substTm (factorSubₛ e idₛ) t) (factorExtₛ e idₛ) fact-unbox≈ {a = a} {Γ = Γ} t e = begin unbox t e -- expand extension e ≡⟨ cong-unbox2≡ ⟩ unbox t (extRAssoc (upLFExt (factorSubₛIdWk e)) (factorExtₛ e idₛ)) -- apply shift-unbox ≈⟨ ⟶-to-≈ (shift-unbox _ _ _) ⟩ unbox (wkTm (LFExtToWk (factorSubₛIdWk e)) t) (factorExtₛ e idₛ) -- rewrite wkTm to substTm ≈⟨ cong-unbox≈ (coh-wkTm-substTm t _) ⟩ unbox (substTm (embWk (LFExtToWk (factorSubₛIdWk e))) t) (factorExtₛ e idₛ) -- show that the subst is the factorisation of the id subst ≡˘⟨ cong1 unbox (cong1 substTm {y = t} (factorSubₛIdWkIsFactorSubₛId e)) ⟩ unbox (substTm (factorSubₛ e idₛ) t) (factorExtₛ e idₛ) ∎ where open SetoidReasoning (Tm-setoid Γ a) rightIdSub : (s : Sub Γ Γ') → s ≈ₛ s ∙ₛ idₛ rightIdSub [] = ≈ₛ-refl rightIdSub (s `, t) = cong-`,≈ₛ (rightIdSub s) (substTmPresId t) rightIdSub (lock s e) = fact-lock≈ s e where -- fact-lock≈ : (s : Sub ΓL Δ) (e : CExt Γ ΓL ΓR) → lock s e ≈ₛ lock (s ∙ₛ factorSubₛ e idₛ) (factorExtₛ e idₛ) fact-lock≈ {Δ = Δ} {Γ = Γ} s e = begin lock s e -- expand extension e ≡⟨ cong-lock2≡ ⟩ lock s (extRAssoc (upLFExt (factorSubₛIdWk e)) (factorExtₛ e idₛ)) -- apply shift-lock≈ₛ ≈⟨ shift-lock≈ₛ _ ⟩ lock (wkSub (LFExtToWk (factorSubₛIdWk e)) s) (factorExtₛ e idₛ) -- apply IH ≈⟨ cong-lock≈ₛ (wkSubPres≈ _ (rightIdSub s)) ⟩ lock (wkSub (LFExtToWk (factorSubₛIdWk e)) (s ∙ₛ idₛ)) (factorExtₛ e idₛ) -- rewrite using coherence between weakening and composing substs (associativity, really) ≡⟨ cong1 lock (coh-wkSub-∙ₛ s idₛ (LFExtToWk (factorSubₛIdWk e))) ⟩ lock (s ∙ₛ wkSub (LFExtToWk (factorSubₛIdWk e)) idₛ) (factorExtₛ e idₛ) -- weakening of id subst is itself a weakening ≡⟨ cong1 lock (cong (s ∙ₛ_) (wkSubId _)) ⟩ lock (s ∙ₛ embWk (LFExtToWk (factorSubₛIdWk e))) (factorExtₛ e idₛ) -- show that the weakening subst is the factorisation of the id subst ≡˘⟨ cong1 lock (cong (s ∙ₛ_) (factorSubₛIdWkIsFactorSubₛId e)) ⟩ lock (s ∙ₛ factorSubₛ e idₛ) (factorExtₛ e idₛ) ∎ where open SetoidReasoning (Sub-setoid Γ (Δ #)) substVarPres⟶ : (v : Var Γ a) → σ ⟶ₛ σ' → substVar σ v ≈ substVar σ' v substVarPres⟶ zero (cong-`,⟶ₛ1 s⟶s') = ≈-refl substVarPres⟶ zero (cong-`,⟶ₛ2 t≈t') = t≈t' substVarPres⟶ (succ v) (cong-`,⟶ₛ1 s⟶s') = substVarPres⟶ v s⟶s' substVarPres⟶ (succ v) (cong-`,⟶ₛ2 t≈t') = ≈-refl substVarPres≈ : (v : Var Γ a) → σ ≈ₛ σ' → substVar σ v ≈ substVar σ' v substVarPres≈ v ε = ≈-refl substVarPres≈ v (inj₁ σ⟶σ' ◅ σ'≈σ'') = ≈-trans (substVarPres⟶ v σ⟶σ') (substVarPres≈ v σ'≈σ'') substVarPres≈ v (inj₂ σ'⟶σ ◅ σ≈σ'') = ≈-˘trans (substVarPres⟶ v σ'⟶σ) (substVarPres≈ v σ≈σ'') substTmPres⟶ : (t : Tm Γ a) → σ ⟶ₛ σ' → substTm σ t ≈ substTm σ' t substTmPres⟶ (var v) r = substVarPres⟶ v r substTmPres⟶ (lam t) r = cong-lam≈ (substTmPres⟶ t (cong-`,⟶ₛ1 (wkSubPres⟶ fresh r))) substTmPres⟶ (app t u) r = cong-app≈ (substTmPres⟶ t r) (substTmPres⟶ u r) substTmPres⟶ (box t) r = cong-box≈ (substTmPres⟶ t (cong-lock⟶ₛ r)) substTmPres⟶ (unbox t e) r = h e r t where h : ∀ (e : CExt Γ ΓL ΓR) (σ⟶σ' : σ ⟶ₛ σ') (t : Tm ΓL (□ a)) {e' : CExt Θ _ ΔR} {e'' : CExt Θ _ ΔR'} → unbox (substTm (factorSubₛ e σ) t) e' ≈ unbox (substTm (factorSubₛ e σ') t) e'' h nil σ⟶ₛσ' t = cong-unbox≈′ (substTmPres⟶ t σ⟶ₛσ') h (ext e) (cong-`,⟶ₛ1 σ⟶σ') t = h e σ⟶σ' t h (ext e) (cong-`,⟶ₛ2 t≈t') t = cong-unbox2≈ h (ext#- e) (cong-lock⟶ₛ σ⟶σ') t = h e σ⟶σ' t h (ext#- e) (shift-lock⟶ₛ {s = σ} w) t {e'} {e''} = let open SetoidReasoning (Tm-setoid _ _) in begin unbox (substTm (factorSubₛ e σ) t) e' ≈⟨ shift-unbox≈ (substTm (factorSubₛ e σ) t) (factorDropsWk (factorExtₛ e σ) w) ⟩ unbox (wkTm (LFExtToWk (factorDropsWk (factorExtₛ e σ) w)) (substTm (factorSubₛ e σ) t)) (subst1 (CExt _) (lCtxₛ-wkSub-comm e σ (LFExtToWk w)) e'') ≡⟨ cong (λ w' → unbox (wkTm w' _) (subst1 (CExt _) (lCtxₛ-wkSub-comm e σ (LFExtToWk w)) e'')) (factorDropsWkIsfactorWk (factorExtₛ e σ) w) ⟩ unbox (wkTm (factorWk (factorExtₛ e σ) (LFExtToWk w)) (substTm (factorSubₛ e σ) t)) (subst1 (CExt _) (lCtxₛ-wkSub-comm e σ (LFExtToWk w)) e'') ≡˘⟨ cong1 unbox (nat-substTm t (factorSubₛ e σ) (factorWk (factorExtₛ e σ) (LFExtToWk w))) ⟩ unbox (substTm (wkSub (factorWk (factorExtₛ e σ) (LFExtToWk w)) (factorSubₛ e σ)) t) (subst1 (CExt _) (lCtxₛ-wkSub-comm e σ (LFExtToWk w)) e'') ≡˘⟨ dcong₃ (λ _Δ s e → unbox (substTm s t) e) (lCtxₛ-wkSub-comm e σ (LFExtToWk w)) (factorSubₛ-wkSub-comm e σ (LFExtToWk w)) refl ⟩ unbox (substTm (factorSubₛ e (wkSub (LFExtToWk w) σ)) t) e'' ∎ substTmPres≈ : (t : Tm Γ a) → (σ≈σ' : σ ≈ₛ σ') → substTm σ t ≈ substTm σ' t substTmPres≈ t ε = ≈-refl substTmPres≈ t (inj₁ σ⟶σ' ◅ σ'≈σ'') = ≈-trans (substTmPres⟶ t σ⟶σ') (substTmPres≈ t σ'≈σ'') substTmPres≈ t (inj₂ σ'⟶σ ◅ σ≈σ'') = ≈-˘trans (substTmPres⟶ t σ'⟶σ) (substTmPres≈ t σ≈σ'')
Generated from commit 2fd14c996b195ef101dff8919e837907ca0a08aa.