open import Chapter1.Logic

open import Data.Unit
open import Data.Sum
open import Data.Product

open import Chapter2.Desc
open import Chapter2.Desc.Fixpoint
open import Chapter2.Desc.Lifting
open import Chapter2.Desc.Induction


module Chapter3.Desc.InitialAlgebra 
         {X : Set}
         (D : Desc)
         (α :  D  X  X)
       where


fold : μ D  X
fold x = induction D  _ -> X) 
                   {xs} ih  α (replace D xs ih))
                  x
  where replace : (D' : Desc)(xs :  D'   (μ D))
                  (ih : [ D' ]^  _  X) xs)   D'  X
        replace `var xs x = x
        replace `1 tt tt = tt
        replace (D  D') (xs , xs') (x , x') = replace D xs x , replace D' xs' x'
        replace (D `+ D') (inj₁ xs) x = inj₁ (replace D xs x)
        replace (D `+ D') (inj₂ xs') x' = inj₂ (replace D' xs' x')
        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)