{-# OPTIONS --without-K #-}
open import Agda.Primitive using (Level; lzero; lsuc; _⊔_)
open import Data.List using (List; []; _∷_)
open import Data.Nat using (ℕ; zero; suc)
open import Data.Product using (_×_) renaming (_,_ to ⟨_,_⟩ )
open import Structures
open import GenericSubstitution
open import Function using (_∘_)
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; sym; trans; cong; cong₂; cong-app; subst)
open Eq.≡-Reasoning
open import Sig
open import Var
module MapFusion (Op : Set) (sig : Op → List Sig) where
open import AbstractBindingTree Op sig
open import Map Op sig
open import GSubst
open import Renaming
open Renaming.WithOpSig Op sig
record QuoteShift {ℓ}(V : Set ℓ) {{S : Shiftable V}}
: Set ℓ where
field {{V-is-Quotable}} : Quotable V
field quote-var→val : ∀ x → “ (var→val{ℓ}{V} x) ” ≡ ` x
quote-shift : ∀ (v : V) → “ ⇑ v ” ≡ rename (↑ 1) “ v ”
open QuoteShift {{...}} public
instance
Var-is-QuoteShift : QuoteShift Var
Var-is-QuoteShift = record { quote-var→val = λ x → refl
; quote-shift = λ v → refl }
ABT-is-QuoteShift : QuoteShift ABT
ABT-is-QuoteShift = record { quote-var→val = λ x → refl
; quote-shift = λ v → refl }
map-rename-fusion : ∀{ℓ}{V₂ V₃ : Set ℓ}
{{_ : Shiftable V₂}} {{_ : Shiftable V₃}}
{{_ : QuoteShift V₂}}{{_ : QuoteShift V₃}}
{ρ₁ : Rename}{σ₂ : GSubst V₂}{σ₃ : GSubst V₃}
→ (M : ABT)
→ σ₂ ○ ρ₁ ≈ σ₃
→ map σ₂ (rename ρ₁ M) ≡ map σ₃ M
map-rename-fusion {ℓ}{V₂}{V₃}{ρ₁ = ρ₁}{σ₂}{σ₃} M σ₂○ρ₁≈σ₃ =
map-map-fusion-ext{lzero}{ℓ}{ℓ}{Var}{V₂}{V₃}{σ₁ = ρ₁}{σ₂}{σ₃}
M σ₂○ρ₁≈σ₃ map-ext
where
map-ext : ∀{ρ₁ : Rename}{σ₂ : GSubst V₂}{σ₃ : GSubst V₃}
→ σ₂ ○ ρ₁ ≈ σ₃ → ext σ₂ ○ ext ρ₁ ≈ ext σ₃
map-ext {ρ₁} {σ₂} {σ₃} σ₂○ρ₁≈σ₃ zero =
trans (quote-var→val{ℓ}{V₂} 0) (sym (quote-var→val{ℓ}{V₃} 0))
map-ext {ρ₁} {σ₂} {σ₃} σ₂○ρ₁≈σ₃ (suc x)=
trans (quote-shift{ℓ}{V₂} (σ₂ (ρ₁ x)))
(sym (trans (quote-shift{ℓ}{V₃} _)
(cong (rename (↑ 1)) (sym (σ₂○ρ₁≈σ₃ x)))))
rename-map-fusion : ∀{ℓ}{V₁ V₃ : Set ℓ}
{{_ : Shiftable V₁}} {{_ : Shiftable V₃}}
{{_ : QuoteShift V₁}}{{_ : QuoteShift V₃}}
{σ₁ : GSubst V₁}{ρ₂ : Rename}{σ₃ : GSubst V₃}
→ (M : ABT)
→ ρ₂ ○ σ₁ ≈ σ₃
→ rename ρ₂ (map σ₁ M) ≡ map σ₃ M
rename-map-fusion {ℓ}{V₁}{V₃}{σ₁ = σ₁}{ρ₂}{σ₃} M ρ₂○σ₁≈σ₃ =
map-map-fusion-ext{ℓ}{lzero}{ℓ}{V₁}{Var}{V₃}{σ₁ = σ₁}{ρ₂}{σ₃}
M ρ₂○σ₁≈σ₃ map-ext
where
map-ext : ∀{σ₁ : GSubst V₁}{ρ₂ : Rename}{σ₃ : GSubst V₃}
→ ρ₂ ○ σ₁ ≈ σ₃ → ext ρ₂ ○ ext σ₁ ≈ ext σ₃
map-ext {σ₁} {ρ₂} {σ₃} ρ₂○σ₁≈σ₃ zero rewrite quote-var→val{ℓ}{V₁} 0
| quote-var→val{ℓ}{V₃} 0 = refl
map-ext {σ₁} {ρ₂} {σ₃} ρ₂○σ₁≈σ₃ (suc x) rewrite quote-shift{ℓ}{V₁} (σ₁ x)
| quote-shift{ℓ}{V₃} (σ₃ x) = begin
rename (0 • ⟰ ρ₂) (map (↑ 1) “ σ₁ x ”)
≡⟨ compose-rename (↑ 1) (0 • ⟰ ρ₂) “ σ₁ x ” ⟩
rename (↑ 1 ⨟ (0 • ⟰ ρ₂)) “ σ₁ x ”
≡⟨ cong (λ □ → rename □ “ σ₁ x ”) (ren-tail (⟰ ρ₂) 0) ⟩
rename (⟰ ρ₂) “ σ₁ x ”
≡⟨ cong (λ □ → rename □ “ σ₁ x ”) (inc=⨟ᵣ↑ ρ₂) ⟩
rename (ρ₂ ⨟ ↑ 1) “ σ₁ x ”
≡⟨ sym (compose-rename ρ₂ (↑ 1) “ σ₁ x ”) ⟩
rename (↑ 1) (rename ρ₂ “ σ₁ x ”)
≡⟨ cong (rename (↑ 1)) (ρ₂○σ₁≈σ₃ x) ⟩
map (↑ 1) “ σ₃ x ”
∎
map-map-fusion : ∀{ℓ}{V₁ V₂ V₃ : Set ℓ}
{{_ : Shiftable V₁}} {{_ : Shiftable V₂}} {{_ : Shiftable V₃}}
{{_ : QuoteShift V₁}}{{_ : QuoteShift V₂}}{{_ : QuoteShift V₃}}
{σ₁ : GSubst V₁}{σ₂ : GSubst V₂}{σ₃ : GSubst V₃}
→ (M : ABT)
→ σ₂ ○ σ₁ ≈ σ₃
→ map σ₂ (map σ₁ M) ≡ map σ₃ M
map-map-fusion {ℓ}{V₁}{V₂}{V₃} M σ₂○σ₁≈σ₃ =
map-map-fusion-ext M σ₂○σ₁≈σ₃ mm-fuse-ext
where
G : ∀{σ₂ : GSubst V₂} → _○_≈_ {lzero}{ℓ}{ℓ}{Var}
((var→val 0) • ⟰ σ₂) (↑ 1) (⟰ σ₂)
G {σ₂} x = refl
H : ∀{σ₂ : GSubst V₂} → ↑ 1 ○ σ₂ ≈ ⟰ σ₂
H {σ₂} x rewrite quote-shift{ℓ}{V₂} (σ₂ x) = refl
mm-fuse-ext : ∀{σ₁ : GSubst V₁}{σ₂ : GSubst V₂}{σ₃ : GSubst V₃}
→ σ₂ ○ σ₁ ≈ σ₃ → ext σ₂ ○ ext σ₁ ≈ ext σ₃
mm-fuse-ext {σ₁}{σ₂}{σ₃} σ₂○σ₁≈σ₃ zero =
begin
map ((var→val 0) • ⟰ σ₂) “ (var→val{ℓ}{V₁} 0) ”
≡⟨ cong (map ((var→val{ℓ}{V₂} 0) • ⟰ σ₂)) (quote-var→val{ℓ}{V₁} 0) ⟩
map ((var→val 0) • ⟰ σ₂) (` 0) ≡⟨⟩
“ ((var→val 0) • ⟰ σ₂) 0 ”
≡⟨⟩
“ (var→val{ℓ}{V₂} 0) ” ≡⟨ (quote-var→val{ℓ}{V₂} 0) ⟩
` 0 ≡⟨ sym (quote-var→val{ℓ}{V₃} 0) ⟩
“ (var→val{ℓ}{V₃} 0) ” ∎
mm-fuse-ext {σ₁}{σ₂}{σ₃} σ₂○σ₁≈σ₃ (suc x) = begin
map ((var→val 0) • ⟰ σ₂) “ ⇑ (σ₁ x) ”
≡⟨ cong (map ((var→val 0) • ⟰ σ₂)) (quote-shift{ℓ}{V₁} (σ₁ x)) ⟩
map ((var→val 0) • ⟰ σ₂) (rename (↑ 1) “ σ₁ x ”)
≡⟨ map-rename-fusion “ σ₁ x ” G ⟩
map (⟰ σ₂) “ σ₁ x ”
≡⟨ sym (rename-map-fusion “ σ₁ x ” H) ⟩
rename (↑ 1) (map σ₂ “ σ₁ x ”) ≡⟨ cong (rename (↑ 1)) (σ₂○σ₁≈σ₃ x) ⟩
rename (↑ 1) “ σ₃ x ” ≡⟨ sym (quote-shift{ℓ}{V₃} (σ₃ x)) ⟩
“ ⇑ (σ₃ x) ” ∎