{-# OPTIONS --without-K --safe #-} module Source.Size.Substitution.Canonical where open import Source.Size open import Util.Prelude infix 0 Sub⊢ infixl 5 _>>_ data Sub (Δ : Ctx) : (Ω : Ctx) → Set where [] : Sub Δ [] Snoc : (σ : Sub Δ Ω) (n : Size Δ) → Sub Δ (Ω ∙ m) variable σ τ σ′ τ′ ι ι′ : Sub Δ Ω subV : Sub Δ Ω → Var Ω → Size Δ subV (Snoc σ n) zero = n subV (Snoc σ n) (suc x) = subV σ x sub : Sub Δ Ω → Size Ω → Size Δ sub σ (var x) = subV σ x sub σ ∞ = ∞ sub σ zero = zero sub σ (suc n) = suc (sub σ n) data Sub⊢ Δ : ∀ Ω (σ : Sub Δ Ω) → Set where [] : Sub⊢ Δ [] [] Snoc : (⊢σ : Sub⊢ Δ Ω σ) (n<m : n < sub σ m) → Sub⊢ Δ (Ω ∙ m) (Snoc σ n) syntax Sub⊢ Δ Ω σ = σ ∶ Δ ⇒ Ω abstract sub-Snoc : ∀ (σ : Sub Δ Ω) n o → sub (Snoc {m = m} σ n) (wk o) ≡ sub σ o sub-Snoc σ n (var x) = refl sub-Snoc σ n ∞ = refl sub-Snoc σ n zero = refl sub-Snoc σ n (suc o) = cong suc (sub-Snoc σ n o) mutual subV-resp-< : σ ∶ Δ ⇒ Ω → var x < n → subV σ x < sub σ n subV-resp-< {x = zero} (Snoc {σ = σ} {n} {m} ⊢σ n<m) (var refl) = subst (n <_) (sym (sub-Snoc σ n m)) n<m subV-resp-< {x = suc x} (Snoc {σ = σ} {n} {m} ⊢σ n<m) (var refl) = subst (subV σ x <_) (sym (sub-Snoc σ n (bound x))) (subV-resp-< ⊢σ (var refl)) subV-resp-< ⊢σ <suc = <suc subV-resp-< ⊢σ (<-trans x<m m<n) = <-trans (subV-resp-< ⊢σ x<m) (sub-resp-< ⊢σ m<n) sub-resp-< : σ ∶ Δ ⇒ Ω → n < m → sub σ n < sub σ m sub-resp-< ⊢σ (var p) = subV-resp-< ⊢σ (var p) sub-resp-< ⊢σ zero<suc = zero<suc sub-resp-< ⊢σ zero<∞ = zero<∞ sub-resp-< ⊢σ (suc<suc n<m) = suc<suc (sub-resp-< ⊢σ n<m) sub-resp-< ⊢σ (suc<∞ n<∞) = suc<∞ (sub-resp-< ⊢σ n<∞) sub-resp-< ⊢σ (<-trans n<o o<m) = <-trans (sub-resp-< ⊢σ n<o) (sub-resp-< ⊢σ o<m) sub-resp-< ⊢σ <suc = <suc Weaken : Sub Δ Ω → Sub (Δ ∙ n) Ω Weaken [] = [] Weaken (Snoc σ m) = Snoc (Weaken σ) (wk m) abstract subV-Weaken : ∀ (σ : Sub Δ Ω) x → subV (Weaken {n = o} σ) x ≡ wk (subV σ x) subV-Weaken (Snoc σ n) zero = refl subV-Weaken (Snoc σ n) (suc x) = subV-Weaken σ x sub-Weaken : ∀ (σ : Sub Δ Ω) n → sub (Weaken {n = o} σ) n ≡ wk (sub σ n) sub-Weaken σ (var x) = subV-Weaken σ x sub-Weaken σ ∞ = refl sub-Weaken σ zero = refl sub-Weaken σ (suc n) = cong suc (sub-Weaken σ n) Weaken⊢ : σ ∶ Δ ⇒ Ω → Weaken σ ∶ Δ ∙ n ⇒ Ω Weaken⊢ [] = [] Weaken⊢ (Snoc {σ = σ} {n} {m} ⊢σ n<m) = Snoc (Weaken⊢ ⊢σ) (subst (wk n <_) (sym (sub-Weaken σ m)) (wk-resp-< n<m)) Lift : (σ : Sub Δ Ω) → Sub (Δ ∙ m) (Ω ∙ n) Lift σ = Snoc (Weaken σ) (var zero) abstract Lift⊢ : σ ∶ Δ ⇒ Ω → m ≡ sub σ n → Lift σ ∶ Δ ∙ m ⇒ Ω ∙ n Lift⊢ {Δ} {σ = σ} {n = n} ⊢σ refl = Snoc (Weaken⊢ ⊢σ) (var (sub-Weaken σ n)) mutual Id : Sub Δ Δ Id {[]} = [] Id {Δ ∙ n} = Lift Id abstract subV-Id : ∀ x → subV (Id {Δ}) x ≡ var x subV-Id zero = refl subV-Id (suc x) = trans (subV-Weaken Id x) (cong wk (subV-Id x)) sub-Id : ∀ n → σ ≡ Id → sub σ n ≡ n sub-Id (var x) refl = subV-Id x sub-Id ∞ _ = refl sub-Id zero _ = refl sub-Id (suc n) p = cong suc (sub-Id n p) abstract Id⊢ : Id ∶ Δ ⇒ Δ Id⊢ {[]} = [] Id⊢ {Δ ∙ n} = Lift⊢ Id⊢ (sym (sub-Id _ refl)) Wk : Sub (Δ ∙ n) Δ Wk = Weaken Id abstract sub-Wk : ∀ n → sub (Wk {Δ} {o}) n ≡ wk n sub-Wk n = trans (sub-Weaken Id n) (cong wk (sub-Id _ refl)) Wk⊢ : Wk ∶ Δ ∙ n ⇒ Δ Wk⊢ = Weaken⊢ Id⊢ Sing : Size Δ → Sub Δ (Δ ∙ m) Sing n = Snoc Id n abstract Sing⊢ : n < m → Sing n ∶ Δ ⇒ Δ ∙ m Sing⊢ {n = n} n<m = Snoc Id⊢ (subst (n <_) (sym (sub-Id _ refl)) n<m) _>>_ : Sub Δ Δ′ → Sub Δ′ Δ″ → Sub Δ Δ″ σ >> [] = [] σ >> Snoc τ n = Snoc (σ >> τ) (sub σ n) abstract subV->> : ∀ (σ : Sub Δ Δ′) (τ : Sub Δ′ Δ″) x → subV (σ >> τ) x ≡ sub σ (subV τ x) subV->> σ (Snoc τ n) zero = refl subV->> σ (Snoc τ n) (suc x) = subV->> σ τ x sub->> : ∀ n → ι ≡ σ >> τ → sub ι n ≡ sub σ (sub τ n) sub->> {σ = σ} {τ} (var x) refl = subV->> σ τ x sub->> ∞ _ = refl sub->> zero _ = refl sub->> (suc n) p = cong suc (sub->> n p) sub->>′ : σ >> τ ≡ σ′ >> τ′ → sub σ (sub τ n) ≡ sub σ′ (sub τ′ n) sub->>′ {σ = σ} {τ = τ} {σ′ = σ′} {τ′} {n} eq = trans (sym (sub->> n refl)) (trans (cong (λ σ → sub σ n) eq) (sub->> n refl)) >>⊢ : σ ∶ Δ ⇒ Δ′ → τ ∶ Δ′ ⇒ Δ″ → σ >> τ ∶ Δ ⇒ Δ″ >>⊢ ⊢σ [] = [] >>⊢ {σ = σ} ⊢σ (Snoc {σ = τ} {n} {m} ⊢τ n<m) = Snoc (>>⊢ ⊢σ ⊢τ) (subst (sub σ n <_) (sym (sub->> m refl)) (sub-resp-< ⊢σ n<m)) Skip : Sub (Δ ∙ n ∙ v0) (Δ ∙ n) Skip = Snoc (Weaken Wk) (var zero) abstract Skip⊢ : Skip ∶ Δ ∙ n ∙ v0 ⇒ Δ ∙ n Skip⊢ {n = n} = Snoc (Weaken⊢ Wk⊢) (<-trans (var refl) (var (trans (sub-Weaken Wk n) (cong wk (sub-Wk n))))) Weaken>> : Weaken σ >> τ ≡ Weaken {n = n} (σ >> τ) Weaken>> {τ = []} = refl Weaken>> {σ = σ} {τ = Snoc τ n} = cong₂ Snoc Weaken>> (sub-Weaken σ n) Snoc>>Weaken : Snoc {m = m} σ n >> Weaken τ ≡ σ >> τ Snoc>>Weaken {τ = []} = refl Snoc>>Weaken {σ = σ} {n = n} {τ = Snoc τ k} = cong₂ Snoc Snoc>>Weaken (sub-Snoc σ n k) id-l : Id >> σ ≡ σ id-l {σ = []} = refl id-l {σ = Snoc σ n} = cong₂ Snoc id-l (sub-Id n refl) id-r : {σ : Sub Δ Ω} → σ >> Id ≡ σ id-r {σ = []} = refl id-r {σ = Snoc σ n} = cong₂ Snoc (trans Snoc>>Weaken id-r) refl >>-assoc : σ >> (τ >> ι) ≡ σ >> τ >> ι >>-assoc {ι = []} = refl >>-assoc {σ = σ} {τ = τ} {ι = Snoc ι n} = cong₂ Snoc >>-assoc (sym (sub->> n refl)) Wk>> : Wk >> σ ≡ Weaken {n = n} σ Wk>> = trans Weaken>> (cong Weaken id-l) Snoc>>Wk : Snoc {m = m} σ n >> Wk ≡ σ Snoc>>Wk = trans Snoc>>Weaken id-r Lift>>Weaken : Lift {m = m} {n} σ >> Weaken τ ≡ Weaken (σ >> τ) Lift>>Weaken = trans Snoc>>Weaken Weaken>> Lift>>Wk : Lift {m = m} {n} σ >> Wk ≡ Wk >> σ Lift>>Wk = trans Lift>>Weaken (trans (sym Wk>>) (cong (Wk >>_) id-r)) Sing>>Weaken : Sing {m = m} n >> Weaken σ ≡ σ Sing>>Weaken = trans Snoc>>Weaken id-l Sing>>Wk : Sing {m = m} n >> Wk ≡ Id Sing>>Wk = trans Snoc>>Weaken id-r Sing>>Lift : ∀ n → Sing (sub σ n) >> Lift {m = m} {o} σ ≡ σ >> Sing n Sing>>Lift n = cong₂ Snoc (trans Sing>>Weaken (sym id-r)) refl Lift>>Lift : Lift {m = m} {n} σ >> Lift {n = o} τ ≡ Lift (σ >> τ) Lift>>Lift = cong₂ Snoc Lift>>Weaken refl Skip>>Weaken : Skip {n = n} >> Weaken σ ≡ Weaken (Weaken σ) Skip>>Weaken = trans Snoc>>Weaken (trans Weaken>> (cong Weaken Wk>>)) Skip>>Lift : Skip >> Lift {m = m} {n} σ ≡ Lift (Lift σ) >> Skip Skip>>Lift = cong₂ Snoc (trans Skip>>Weaken (sym (trans Lift>>Weaken (cong Weaken (trans Snoc>>Weaken id-r))))) refl Lift-Id : Lift {m = m} Id ≡ Id Lift-Id = refl LiftSing>>Wk>>Wk : Lift {m = o} {m} (Sing n) >> (Wk >> Wk) ≡ Wk LiftSing>>Wk>>Wk {n = n} {m} = let open ≡-Reasoning in begin Lift (Sing n) >> (Wk >> Wk) ≡⟨ cong (Lift (Sing n) >>_) Wk>> ⟩ Lift (Sing n) >> (Weaken Wk) ≡⟨ Lift>>Weaken ⟩ Weaken (Sing n >> Weaken Id) ≡⟨ cong Weaken Sing>>Weaken ⟩ Wk ∎ LiftSing>>Skip : Lift {m = m} (Sing {m = m} n) >> Skip ≡ Sing {m = o} (var zero) >> Lift Wk LiftSing>>Skip {n = n} = cong₂ Snoc go refl where go : Lift (Sing n) >> Weaken Wk ≡ Sing (var zero) >> Weaken Wk go = let open ≡-Reasoning in begin Lift (Sing n) >> Weaken Wk ≡⟨ Lift>>Weaken ⟩ Weaken (Sing n >> Weaken Id) ≡⟨ cong Weaken Sing>>Wk ⟩ Wk ≡⟨ sym Sing>>Weaken ⟩ Sing (var zero) >> Weaken Wk ∎ LiftLift>>Skip : Lift (Lift {m = m} {n} σ) >> Skip ≡ Skip >> Lift σ LiftLift>>Skip = cong₂ Snoc (trans Lift>>Weaken (sym (trans Skip>>Weaken (cong Weaken (sym Snoc>>Wk))))) refl