open import Function

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

open import Chapter1.Logic

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


module Chapter2.Desc.Induction
          (D : Desc)
          (P : μ D  Set) where

DAlg : Set
DAlg = [ D ]^ P  P  ⟨_⟩

module Induction (α : DAlg) where

  mutual
    induction : (x : μ D)  P x
    induction  xs  = α (hyps D xs)

    hyps : (D' : Desc)(xs :  D'  (μ D))  [ D' ]^ P xs
    hyps `1 tt = tt
    hyps `var xs = induction xs
    hyps (T  T') (t , t') = hyps T t , hyps T' t'
    hyps (T `+ T') (inj₁ t) = hyps T t
    hyps (T `+ T') (inj₂ t') = hyps T' t'
    hyps ( S T) (s , xs) = hyps (T s) xs
    hyps ( S T) f = λ s  hyps (T s) (f s)

induction : DAlg  (x : μ D)  P x
induction = Induction.induction