module Description where
open import Prelude
open import Data.Unit using (⊤; tt)
open import Data.Product using (Σ; _,_; _×_)
data RDesc (I : Set) : Set₁ where
∎ : RDesc I
ṿ : (i : I) → RDesc I
σ : (S : Set) (D : S → RDesc I) → RDesc I
_*_ : (D E : RDesc I) → RDesc I
syntax σ S (λ s → D) = σ[ s ∶ S ] D
⟦_⟧ : ∀ {I} → RDesc I → (I → Set) → Set
⟦ ∎ ⟧ X = ⊤
⟦ ṿ i ⟧ X = X i
⟦ σ S D ⟧ X = Σ[ s ∶ S ] ⟦ D s ⟧ X
⟦ D * E ⟧ X = ⟦ D ⟧ X × ⟦ E ⟧ X
data Desc (I : Set) : Set₁ where
wrap : (I → RDesc I) → Desc I
_at_ : ∀ {I} → Desc I → I → RDesc I
(wrap D) at i = D i
Ḟ : ∀ {I} → Desc I → (I → Set) → (I → Set)
Ḟ D X i = ⟦ D at i ⟧ X
_⇒_ : ∀ {I} → (I → Set) → (I → Set) → Set
X ⇒ Y = ∀ {i} → X i → Y i
infixr 1 _⇒_
data μ {I} (D : Desc I) : I → Set where
con : Ḟ D (μ D) ⇒ μ D
decon : ∀ {I} {D : Desc I} → μ D ⇒ Ḟ D (μ D)
decon (con xs) = xs
mutual
fold : ∀ {I X} {D : Desc I} → Ḟ D X ⇒ X → μ D ⇒ X
fold {D = D} φ {i} (con ds) = φ (mapFold D (D at i) φ ds)
mapFold : ∀ {I} (D : Desc I) (E : RDesc I) → ∀ {X} → (Ḟ D X ⇒ X) → ⟦ E ⟧ (μ D) → ⟦ E ⟧ X
mapFold D ∎ φ _ = _
mapFold D (ṿ i) φ d = fold φ d
mapFold D (σ S E) φ (s , ds) = s , mapFold D (E s) φ ds
mapFold D (E * E') φ (ds , ds') = mapFold D E φ ds , mapFold D E' φ ds'
All : ∀ {I} (D : RDesc I) {X : I → Set} (P : ∀ {i} → X i → Set) → ⟦ D ⟧ X → Set
All ∎ P _ = ⊤
All (ṿ i) P x = P x
All (σ S D) P (s , xs) = All (D s) P xs
All (D * E) P (xs , xs') = All D P xs × All E P xs'
mutual
induction : ∀ {I} (D : Desc I) (P : ∀ {i} → μ D i → Set) →
(∀ {i} (ds : Ḟ D (μ D) i) → All (D at i) P ds → P (con ds)) →
∀ {i} (d : μ D i) → P d
induction D P ih {i} (con ds) = ih ds (everywhereInduction D (D at i) P ih ds)
everywhereInduction :
∀ {I} (D : Desc I) (E : RDesc I)
(P : ∀ {i} → μ D i → Set) →
(∀ {i} (ds : Ḟ D (μ D) i) → All (D at i) P ds → P (con ds)) →
(ds : ⟦ E ⟧ (μ D)) → All E P ds
everywhereInduction D ∎ P ih _ = _
everywhereInduction D (ṿ i) P ih d = induction D P ih d
everywhereInduction D (σ S E) P ih (s , ds) = everywhereInduction D (E s) P ih ds
everywhereInduction D (E * E') P ih (ds , ds') = everywhereInduction D E P ih ds ,
everywhereInduction D E' P ih ds'