{-# OPTIONS --safe --with-K #-} open import Prelude module Generics.Ornament where open import Generics.Telescope open import Generics.Description open import Generics.Algebra open import Generics.Recursion private variable A : Set ℓ m n : ℕ rb rb' : RecB cb cb' : ConB cbs cbs' : ConBs module _ {I : Set ℓⁱ} {J : Set ℓʲ} (e : I → J) where infixr 5 _∷_ infix 5 ∺_ data RecO : RecD I rb → RecD J rb' → Setω where ι : ∀ {i j} ⦃ eq : e i ≡ j ⦄ → RecO (ι i) (ι j) π : {D : A → RecD I rb} {E : A → RecD J rb} (O : (a : A) → RecO (D a) (E a)) → RecO (π A D) (π A E) data ConO : ConD I cb → ConD J cb' → Setω where ι : ∀ {i j} ⦃ eq : e i ≡ j ⦄ → ConO (ι i) (ι j) σ : {D : A → ConD I cb} {E : A → ConD J cb'} (O : (a : A) → ConO (D a) (E a)) → ConO (σ A D) (σ A E) Δ : {D : A → ConD I cb} {E : ConD J cb'} (O : (a : A) → ConO (D a) E ) → ConO (σ A D) E ∇ : {D : ConD I cb} {E : A → ConD J cb'} (a : A) (O : ConO D (E a)) → ConO D (σ A E) ρ : {R : RecD I rb} {S : RecD J rb} {D : ConD I cb} {E : ConD J cb'} (O : RecO R S) (O' : ConO D E) → ConO (ρ R D) (ρ S E) syntax π (λ a → D) = π[ a ] D syntax σ (λ a → D) = σ[ a ] D syntax Δ (λ a → D) = Δ[ a ] D data ConOs : ConDs I cbs → ConDs J cbs' → Setω where [] : ConOs [] [] _∷_ : {D : ConD I cb} {E : ConD J cb'} {Ds : ConDs I cbs} {Es : ConDs J cbs'} (O : ConO D E) (Os : ConOs Ds (E ∷ Es)) → ConOs (D ∷ Ds) (E ∷ Es) ∺_ : {E : ConD J cb} {Ds : ConDs I cbs} {Es : ConDs J cbs'} (Os : ConOs Ds Es ) → ConOs Ds (E ∷ Es) module _ {I : Set ℓⁱ} {J : Set ℓʲ} {e : I → J} where eraseʳ : {D : RecD I rb} {E : RecD J rb} (O : RecO e D E) {X : J → Set ℓ} → ⟦ D ⟧ʳ (X ∘ e) → ⟦ E ⟧ʳ X eraseʳ (ι ⦃ eq ⦄) x = subst _ eq x eraseʳ (π O) xs = λ a → eraseʳ (O a) (xs a) eraseᶜ : {D : ConD I cb} {E : ConD J cb'} (O : ConO e D E) {X : J → Set ℓˣ} {i : I} → ⟦ D ⟧ᶜ (X ∘ e) i → ⟦ E ⟧ᶜ X (e i) eraseᶜ (ι ⦃ eq ⦄) eq' = trans (sym eq) (cong _ eq') eraseᶜ (σ O ) (a , xs) = a , eraseᶜ (O a) xs eraseᶜ (Δ O ) (a , xs) = eraseᶜ (O a) xs eraseᶜ (∇ a O ) xs = a , eraseᶜ O xs eraseᶜ (ρ O O') (x , xs) = eraseʳ O x , eraseᶜ O' xs eraseᶜˢ : {Ds : ConDs I cbs} {Es : ConDs J cbs'} (Os : ConOs e Ds Es) {X : J → Set ℓˣ} {i : I} → ⟦ Ds ⟧ᶜˢ (X ∘ e) i → ⟦ Es ⟧ᶜˢ X (e i) eraseᶜˢ (O ∷ Os) (inl xs) = inl (eraseᶜ O xs) eraseᶜˢ (O ∷ Os) (inr xs) = eraseᶜˢ Os xs eraseᶜˢ ( ∺ Os) xs = inr (eraseᶜˢ Os xs) record PDataO (D E : PDataD) : Setω where field param : ⟦ PDataD.Param D ⟧ᵗ → ⟦ PDataD.Param E ⟧ᵗ index : (ps : ⟦ PDataD.Param D ⟧ᵗ) → ⟦ PDataD.Index D ps ⟧ᵗ → ⟦ PDataD.Index E (param ps) ⟧ᵗ applyP : (ps : ⟦ PDataD.Param D ⟧ᵗ) → ConOs (index ps) (PDataD.applyP D ps) (PDataD.applyP E (param ps)) record DataO (D E : DataD) : Setω where field level : DataD.Levels D → DataD.Levels E applyL : (ℓs : DataD.Levels D) → PDataO (DataD.applyL D ℓs) (DataD.applyL E (level ℓs)) eraseᵖᵈ : {D E : PDataD} (O : PDataO D E) {ps : ⟦ PDataD.Param D ⟧ᵗ} → let qs = PDataO.param O ps; index = PDataO.index O ps in {X : ⟦ PDataD.Index E qs ⟧ᵗ → Set ℓ} {i : ⟦ PDataD.Index D ps ⟧ᵗ} → ⟦ D ⟧ᵖᵈ (X ∘ index) i → ⟦ E ⟧ᵖᵈ X (index i) eraseᵖᵈ O {ps} = eraseᶜˢ (PDataO.applyP O ps) eraseᵈ : {D E : DataD} (O : DataO D E) {ℓs : DataD.Levels D} → let Dᵖ = DataD.applyL D ℓs Eᵖ = DataD.applyL E (DataO.level O ℓs) Oᵖ = DataO.applyL O ℓs in {ps : ⟦ PDataD.Param Dᵖ ⟧ᵗ} → let qs = PDataO.param Oᵖ ps; index = PDataO.index Oᵖ ps in {X : ⟦ PDataD.Index Eᵖ qs ⟧ᵗ → Set ℓ} {is : ⟦ PDataD.Index Dᵖ ps ⟧ᵗ} → ⟦ D ⟧ᵈ (X ∘ index) is → ⟦ E ⟧ᵈ X (index is) eraseᵈ O {ℓs} = eraseᵖᵈ (DataO.applyL O ℓs) forget : ∀ (m n : Name) {D M} ⦃ DC : Named m (DataC D M) ⦄ → ∀ {E N} ⦃ EC : Named n (DataC E N) ⦄ ⦃ O : DataO D E ⦄ → FoldP forget _ _ {D} ⦃ named DC ⦄ {N = N} ⦃ named EC ⦄ ⦃ O ⦄ = record { Conv = DC ; #levels = DataD.#levels D ; level = id ; Param = λ ℓs → PDataD.Param (DataD.applyL D ℓs) ; param = id ; ParamV = constTelInfo hidden ; ParamN = constTelInfo "p" ; Carrier = λ ℓs ps is → let Oᵖ = DataO.applyL O ℓs in N (DataO.level O ℓs) (PDataO.param Oᵖ ps) (PDataO.index Oᵖ ps is) ; algebra = λ _ → DataC.toN EC ∘ eraseᵈ O }