{-# OPTIONS --safe --without-K #-} open import Prelude module Generics.Recursion where open import Agda.Builtin.Reflection public using (Name) open import Generics.Telescope open import Generics.Description open import Generics.Algebra private variable rb : RecB cb : ConB cbs : ConBs DataT : DataD → Setω DataT D = Carriers D (λ ℓs → PDataD.dlevel (DataD.applyL D ℓs)) record DataC (D : DataD) (N : DataT D) : Setω where constructor datac field toN : Algs D N fromN : Coalgs D N fromN-toN : ∀ {ℓs ps is} (ns : ⟦ D ⟧ᵈ (N ℓs ps) is) → fromN (toN ns) ≡ ns toN-fromN : ∀ {ℓs ps is} (n : N ℓs ps is) → toN (fromN n ) ≡ n record Named (n : Name) (A : Setω) : Setω where constructor named field unNamed : A open Named public findNamed : (n : Name) (A : Setω) → ⦃ Named n A ⦄ → A findNamed _ _ ⦃ named a ⦄ = a findDataC : ∀ (n : Name) {D N} → ⦃ Named n (DataC D N) ⦄ → DataC D N findDataC n = findNamed n _ findDataD : ∀ (n : Name) {D N} → ⦃ Named n (DataC D N) ⦄ → DataD findDataD _ {D} = D record FoldP : Setω where field {Desc} : DataD {Native} : DataT Desc Conv : DataC Desc Native #levels : ℕ Levels : Set Levels = Level ^ #levels field level : Levels → DataD.Levels Desc {plevel} : Levels → Level Param : ∀ ℓs → Tel (plevel ℓs) ParamV : ∀ {ℓs} → TelInfo Visibility (Param ℓs) ParamN : ∀ {ℓs} → TelInfo String (Param ℓs) param : ∀ {ℓs} → ⟦ Param ℓs ⟧ᵗ → ⟦ PDataD.Param (DataD.applyL Desc (level ℓs)) ⟧ᵗ {clevel} : Levels → Level Carrier : ∀ ℓs (ps : ⟦ Param ℓs ⟧ᵗ) → Carrierᶜˢ (PDataD.applyP (DataD.applyL Desc (level ℓs)) (param ps)) (clevel ℓs) algebra : ∀ {ℓs} (ps : ⟦ Param ℓs ⟧ᵗ) → Algᶜˢ (PDataD.applyP (DataD.applyL Desc (level ℓs)) (param ps)) (Carrier ℓs ps) FoldT : FoldP → Setω FoldT P = let open FoldP P in ∀ (ℓs) → let open PDataD (DataD.applyL Desc (level ℓs)) in (ps : ⟦ FoldP.Param P ℓs ⟧ᵗ) {is : ⟦ Index (param ps) ⟧ᵗ} → Native (level ℓs) (param ps) is → Carrier ℓs ps is FoldNT : (P : FoldP) → let open FoldP P in (ℓs : Levels) → let open PDataD (DataD.applyL Desc (level ℓs)) hiding (plevel) in Set (alevel ⊔ ilevel ⊔ FoldP.plevel P ℓs ⊔ clevel ℓs) FoldNT P ℓs = Curriedᵗ (FoldP.Param P ℓs) (FoldP.ParamV P) λ ps → Curriedᵗ (Index (param ps)) (constTelInfo hidden) λ is → Native (level ℓs) (param ps) is → Carrier ℓs ps is where open FoldP P open PDataD (DataD.applyL Desc (level ℓs)) fold-base : (P : FoldP) → ∀ {ℓs} → FoldNT P ℓs → FoldNT P ℓs fold-base P {ℓs} rec = let open FoldP P in curryᵗ λ ps → curryᵗ λ is → algebra ps {is} ∘ fmapᵈ Desc (λ {is} → uncurryᵗ (uncurryᵗ rec ps) is) ∘ DataC.fromN Conv record FoldC (P : FoldP) (f : FoldT P) : Setω where field equation : let open FoldP P in ∀ {ℓs ps is} (ns : ⟦ Desc ⟧ᵈ (Native (level ℓs) (param ps)) is) → f ℓs ps (DataC.toN Conv ns) ≡ algebra ps (fmapᵈ Desc (f ℓs ps) ns) record IndP : Setω where field {Desc} : DataD {Native} : DataT Desc Conv : DataC Desc Native #levels : ℕ Levels : Set Levels = Level ^ #levels field level : Levels → DataD.Levels Desc {plevel} : Levels → Level Param : ∀ ℓs → Tel (plevel ℓs) param : ∀ {ℓs} → ⟦ Param ℓs ⟧ᵗ → ⟦ PDataD.Param (DataD.applyL Desc (level ℓs)) ⟧ᵗ ParamV : ∀ {ℓs} → TelInfo Visibility (Param ℓs) ParamN : ∀ {ℓs} → TelInfo String (Param ℓs) {clevel} : Levels → Level Carrier : ∀ ℓs (ps : ⟦ Param ℓs ⟧ᵗ) → IndCarrierᶜˢ (PDataD.applyP (DataD.applyL Desc (level ℓs)) (param ps)) (Native (level ℓs) (param ps)) (clevel ℓs) algebra : ∀ {ℓs} (ps : ⟦ Param ℓs ⟧ᵗ) → IndAlgᶜˢ (PDataD.applyP (DataD.applyL Desc (level ℓs)) (param ps)) (DataC.toN Conv) (Carrier ℓs ps) lzero IndT : IndP → Setω IndT P = let open IndP P in ∀ ℓs → let open PDataD (DataD.applyL Desc (level ℓs)) in (ps : ⟦ IndP.Param P ℓs ⟧ᵗ) {is : ⟦ Index (param ps) ⟧ᵗ} → (n : Native (level ℓs) (param ps) is) → Carrier ℓs ps is n IndNT : (P : IndP) → let open IndP P in (ℓs : Levels) → let open PDataD (DataD.applyL Desc (level ℓs)) hiding (plevel) in Set (alevel ⊔ ilevel ⊔ plevel ℓs ⊔ clevel ℓs) IndNT P ℓs = Curriedᵗ (IndP.Param P ℓs) ParamV λ ps → Curriedᵗ (Index (param ps)) (constTelInfo hidden) λ is → (n : Native (level ℓs) (param ps) is) → Carrier ℓs ps is n where open IndP P open PDataD (DataD.applyL Desc (level ℓs)) ind-base : (P : IndP) → (∀ {ℓs} → IndNT P ℓs → IndNT P ℓs) ind-base P {ℓs} rec = let open IndP P in curryᵗ λ ps → curryᵗ λ is n → subst (Carrier ℓs ps is) (DataC.toN-fromN Conv n) (algebra ps _ (ind-fmapᵈ Desc (λ {is} → uncurryᵗ (uncurryᵗ rec ps) is) (DataC.fromN Conv n))) record IndC (P : IndP) (f : IndT P) : Setω where field equation : let open IndP P in ∀ {ℓs ps is} (ns : ⟦ Desc ⟧ᵈ (Native (level ℓs) (param ps)) is) → f _ ps (DataC.toN Conv ns) ≡ algebra ps _ (ind-fmapᵈ Desc (f _ ps) ns)