{-# OPTIONS --safe --sized-types #-} module Data.Var.Varlike where open import Data.List.Base hiding (lookup ; [_]) open import Function open import Relation.Binary.PropositionalEquality hiding ([_]) open import Relation.Unary using (IUniversal; _⊢_; _⇒_) open import Data.Var open import Data.Pred as Pred hiding (All) open import Data.Relation open import Data.Environment open import Generic.Syntax private variable I : Set σ : I Γ Δ : List I 𝓥 𝓥₁ 𝓥₂ 𝓒 𝓥ᴬ 𝓥ᴮ 𝓒ᴬ 𝓒ᴮ : I ─Scoped record VarLike (𝓥 : I ─Scoped) : Set where field th^𝓥 : Thinnable (𝓥 σ) new : ∀[ (σ ∷_) ⊢ 𝓥 σ ] base : (Γ ─Env) 𝓥 Γ base {Γ = []} = ε base {Γ = σ ∷ Γ} = th^Env th^𝓥 base weaken ∙ new freshʳ : (Δ : List I) → (Γ ─Env) 𝓥 (Δ ++ Γ) freshʳ Δ = th^Env th^𝓥 base (pack (injectʳ Δ)) freshˡ : (Δ : List I) → (Γ ─Env) 𝓥 (Γ ++ Δ) freshˡ k = th^Env th^𝓥 base (pack (injectˡ _)) singleton : 𝓥 σ Γ → (σ ∷ Γ ─Env) 𝓥 Γ singleton v = base ∙ v open VarLike public vl^Var : VarLike {I} Var new vl^Var = z th^𝓥 vl^Var = th^Var lookup-base^Var : (k : Var σ Γ) → lookup (base vl^Var) k ≡ k lookup-base^Var z = refl lookup-base^Var (s k) = cong s (lookup-base^Var k) reify : VarLike 𝓥 → ∀ Δ i → Kripke 𝓥 𝓒 Δ i Γ → Scope 𝓒 Δ i Γ reify vl^𝓥 [] i b = b reify vl^𝓥 Δ@(_ ∷ _) i b = b (freshʳ vl^Var Δ) (freshˡ vl^𝓥 _) module _ (vl^𝓥 : VarLike 𝓥) where lift : ∀ Θ → (Γ ─Env) 𝓥 Δ → ((Θ ++ Γ) ─Env) 𝓥 (Θ ++ Δ) lift Θ ρ = freshˡ vl^𝓥 _ >> th^Env (th^𝓥 vl^𝓥) ρ (freshʳ vl^Var Θ) weaken-is-fresh : All Eqᴿ Γ weaken (freshʳ vl^Var (σ ∷ [])) lookupᴿ weaken-is-fresh k = cong s (sym (lookup-base^Var k)) module _ {I : Set} {𝓥 : I ─Scoped} where open ≡-Reasoning freshʳ->> : (Δ : List I) {Γ Θ : List I} (ρ₁ : (Δ ─Env) 𝓥 Θ) (ρ₂ : (Γ ─Env) 𝓥 Θ) {i : I} (v : Var i Γ) → lookup (ρ₁ >> ρ₂) (lookup (freshʳ vl^Var Δ) v) ≡ lookup ρ₂ v freshʳ->> Δ ρ₁ ρ₂ v = begin lookup (ρ₁ >> ρ₂) (lookup (freshʳ vl^Var Δ) v) ≡⟨ injectʳ->> ρ₁ ρ₂ (lookup (base vl^Var) v) ⟩ lookup ρ₂ (lookup (base vl^Var) v) ≡⟨ cong (lookup ρ₂) (lookup-base^Var v) ⟩ lookup ρ₂ v ∎ module _ (𝓡^𝓥 : Rel 𝓥₁ 𝓥₂) where record VarLikeᴿ (vl₁ : VarLike 𝓥₁) (vl₂ : VarLike 𝓥₂) : Set where field newᴿ : rel 𝓡^𝓥 σ {σ ∷ Γ} (new vl₁) (new vl₂) thᴿ : (ρ : Thinning Γ Δ) {v₁ : 𝓥₁ σ Γ} {v₂ : 𝓥₂ σ Γ} → rel 𝓡^𝓥 σ v₁ v₂ → rel 𝓡^𝓥 σ (th^𝓥 vl₁ v₁ ρ) (th^𝓥 vl₂ v₂ ρ) baseᴿ : All 𝓡^𝓥 Γ (base vl₁) (base vl₂) baseᴿ {[] } = packᴿ λ () baseᴿ {i ∷ Γ} = (thᴿ weaken <$>ᴿ baseᴿ) ∙ᴿ newᴿ freshˡᴿ : ∀ Γ → All 𝓡^𝓥 Δ (freshˡ vl₁ Γ) (freshˡ vl₂ Γ) freshˡᴿ n = thᴿ _ <$>ᴿ baseᴿ freshʳᴿ : ∀ Γ → All 𝓡^𝓥 Δ (freshʳ vl₁ Γ) (freshʳ vl₂ Γ) freshʳᴿ n = thᴿ _ <$>ᴿ baseᴿ module _ (vl^𝓥 : VarLike 𝓥) where vl^Refl : VarLikeᴿ Eqᴿ vl^𝓥 vl^𝓥 VarLikeᴿ.newᴿ vl^Refl = refl VarLikeᴿ.thᴿ vl^Refl = λ σ → cong (λ v → th^𝓥 vl^𝓥 v σ) module _ (𝓥ᴾ : Pred {I} 𝓥) (𝓒ᴾ : Pred {I} 𝓒) where Kripkeᴾ : ∀ Δ τ → ∀[ Kripke 𝓥 𝓒 Δ τ ⇒ const Set ] Kripkeᴾ [] τ k = pred 𝓒ᴾ τ k Kripkeᴾ Δ@(_ ∷ _) τ k = ∀ {Θ} th {ρ : (Δ ─Env) 𝓥 Θ} → Pred.All 𝓥ᴾ Δ ρ → pred 𝓒ᴾ τ (k th ρ) module _ (𝓥ᴿ : Rel {I} 𝓥ᴬ 𝓥ᴮ) (𝓒ᴿ : Rel {I} 𝓒ᴬ 𝓒ᴮ) where Kripkeᴿ : ∀ Δ i → ∀[ Kripke 𝓥ᴬ 𝓒ᴬ Δ i ⇒ Kripke 𝓥ᴮ 𝓒ᴮ Δ i ⇒ const Set ] Kripkeᴿ [] σ kᴬ kᴮ = rel 𝓒ᴿ σ kᴬ kᴮ Kripkeᴿ Δ@(_ ∷ _) σ kᴬ kᴮ = ∀ {Θ} (ρ : Thinning _ Θ) {vsᴬ vsᴮ} → All 𝓥ᴿ Δ vsᴬ vsᴮ → rel 𝓒ᴿ σ (kᴬ ρ vsᴬ) (kᴮ ρ vsᴮ)