{-# OPTIONS --cubical-compatible --safe #-}
module Data.W where
open import Level using (Level; _⊔_)
open import Function.Base using (_$_; _∘_; const)
open import Data.Product.Base using (_,_; -,_; proj₂)
open import Data.Container.Core using (Container; ⟦_⟧; Shape; Position; _⇒_; ⟪_⟫)
open import Data.Container.Relation.Unary.All using (□; all)
open import Relation.Nullary.Negation using (¬_)
open import Agda.Builtin.Equality using (_≡_; refl)
private
variable
s p s₁ s₂ p₁ p₂ ℓ : Level
C : Container s p
C₁ : Container s₁ p₁
C₂ : Container s₂ p₂
data W (C : Container s p) : Set (s ⊔ p) where
sup : ⟦ C ⟧ (W C) → W C
sup-injective₁ : ∀ {s t : Shape C} {f : Position C s → W C} {g} →
sup (s , f) ≡ sup (t , g) → s ≡ t
sup-injective₁ refl = refl
head : W C → Shape C
head (sup (x , f)) = x
tail : (x : W C) → Position C (head x) → W C
tail (sup (x , f)) = f
map : (m : C₁ ⇒ C₂) → W C₁ → W C₂
map m (sup (x , f)) = sup (⟪ m ⟫ (x , λ p → map m (f p)))
module _ (P : W C → Set ℓ)
(alg : ∀ {t} → □ C P t → P (sup t)) where
induction : (w : W C) → P w
induction (sup (s , f)) = alg $ all (induction ∘ f)
module _ {P : Set ℓ} (alg : ⟦ C ⟧ P → P) where
foldr : W C → P
foldr = induction (const P) (alg ∘ -,_ ∘ □.proof)
inhabited⇒empty : (∀ s → Position C s) → ¬ W C
inhabited⇒empty b = foldr ((_$ b _) ∘ proj₂)