open import Chapter1.Logic open import Data.Unit open import Data.Product open import Chapter2.IDesc open import Chapter2.IDesc.Fixpoint open import Chapter2.IDesc.Lifting open import Chapter2.IDesc.Induction module Chapter3.IDesc.InitialAlgebra {I : Set}{X : I → Set} (D : func I I) (α : ⟦ D ⟧func X ⇒ X) where fold : μ D ⇒ X fold x = induction D (λ {i} _ → X i) (λ {i}{xs} ih → α (replace (func.out D i) xs ih)) x where replace : (D' : IDesc I)(xs : ⟦ D' ⟧ (μ D)) → (ih : [ D' ]^h (λ {i} _ → X i) xs) → ⟦ D' ⟧ X replace (`var i) xs x = x replace `1 tt tt = tt replace (D `× D') (xs , xs') (x , x') = replace D xs x , replace D' xs' x' replace (`σ n T) (k , xs) ih = k , replace (T k) xs ih replace (`Σ S T) (s , xs) ih = s , replace (T s) xs ih replace (`Π S T) xs ih = λ s → replace (T s) (xs s) (ih s)