{-# OPTIONS --without-K --cubical-compatible #-}
open import common
open import inductive-repair.indspec
open import inductive-repair.config
module inductive-repair.wtype-config {ℓ : Level} where
WTypeArity : {ℓ : Level} → (A : Type ℓ) → (B : A → Type ℓ) → ⊤ {ℓ} → ConstrArity {ℓ}
WTypeArity A B _ = Nonrec A (λ a → Rec (B a) Done)
WTypeSignature : {ℓ : Level} → (A : Type ℓ) → (B : A → Type ℓ) → Signature
WTypeSignature _ _ .Signature.Op = ⊤
WTypeSignature {ℓ} A B .Signature.arity = WTypeArity {ℓ} A B
WTypeIndAlg : {ℓ : Level} → (A : Type ℓ) → (B : A → Type ℓ) → (C : Type ℓ) → Type (lsuc ℓ)
WTypeIndAlg {ℓ} A B C = IndAlg (WTypeSignature {ℓ} A B) C
WTypeConfig : {ℓ : Level} → (A : Type ℓ) → (B : A → Type ℓ) → (C D : Type ℓ) → Type (lsuc ℓ)
WTypeConfig {ℓ} A B C D = Config (WTypeSignature {ℓ} A B) C D
module _ {sig : Signature {ℓ}} where
arity = Signature.arity sig
Op = Signature.Op sig
recPos : (cs : ConstrArity {ℓ}) → Args cs (⊤ {ℓ}) → Type ℓ
recPos Done _ = ⊥
recPos (Nonrec A k) (a , s) = recPos (k a) s
recPos (Rec D cs) (_ , s) = D ⊎ recPos cs s
β-emb-pos : {D X C : Type ℓ} (r : D → C) (q : X → C) → D ⊎ X → C
β-emb-pos r q (inl d) = r d
β-emb-pos r q (inr x) = q x
β-emb : (D : Type ℓ) (cs : ConstrArity {ℓ}) {C : Type ℓ} → (D → C) →
Σ (Args cs (⊤ {ℓ})) (λ s' → recPos cs s' → C) →
Σ (Args (Rec D cs) (⊤ {ℓ})) (λ s' → recPos (Rec D cs) s' → C)
β-emb D cs r q = (((λ _ → tt) , fst q) , β-emb-pos r (snd q))
convert : (cs : ConstrArity {ℓ}) {C : Type ℓ} → Args cs C →
Σ (Args cs (⊤ {ℓ})) (λ s → recPos cs s → C)
convert Done _ = (tt , λ ())
convert (Nonrec A k) (a , args) =
let (s , p) = convert (k a) args in ((a , s) , p)
convert (Rec D cs) (r , args) = β-emb D cs r (convert cs args)
unconvert : (cs : ConstrArity {ℓ}) {C : Type ℓ} →
Σ (Args cs (⊤ {ℓ})) (λ s → recPos cs s → C) →
Args cs C
unconvert Done _ = tt
unconvert (Nonrec A k) ((a , s) , p) = (a , unconvert (k a) (s , p))
unconvert (Rec D cs) ((_ , s) , p) =
((λ d → p (inl d)) , unconvert cs (s , λ z → p (inr z)))
unconvert-convert : {C : Type ℓ} (cs : ConstrArity {ℓ}) (args : Args cs C) →
unconvert cs (convert cs args) ≡ args
unconvert-convert Done _ = refl
unconvert-convert (Nonrec A k) (a , args) = ap (λ z → (a , z)) (unconvert-convert (k a) args)
unconvert-convert (Rec D cs) (r , args) = ap (λ z → (r , z)) (unconvert-convert cs args)
pwr-of : {D : Type ℓ} (cs : ConstrArity {ℓ}) {C : Type ℓ}
{s : Args cs (⊤ {ℓ})}
(p : recPos (Rec D cs) ((λ _ → tt) , s) → C) →
(x : D ⊎ recPos cs s) →
β-emb-pos (λ d → p (inl d)) (λ z → p (inr z)) x ≡ p x
pwr-of cs p (inl d) = refl
pwr-of cs p (inr z) = refl
γ-fix : (D : Type ℓ) (cs : ConstrArity {ℓ}) {C : Type ℓ}
(s : Args cs (⊤ {ℓ}))
(p : recPos (Rec D cs) ((λ _ → tt) , s) → C) →
β-emb D cs (λ d → p (inl d)) (s , λ z → p (inr z))
≡ (((λ _ → tt) , s) , p)
γ-fix D cs s p = Σ-≡-intro refl (ext (pwr-of cs p))
convert-unconvert : {C : Type ℓ} (cs : ConstrArity {ℓ})
(sp : Σ (Args cs (⊤ {ℓ})) (λ s → recPos cs s → C)) →
convert cs (unconvert cs sp) ≡ sp
convert-unconvert Done (tt , p) = Σ-≡-intro refl (ext (λ ()))
convert-unconvert (Nonrec A k) ((a , s) , p) =
ap (λ q → ((a , fst q) , snd q)) (convert-unconvert (k a) (s , p))
convert-unconvert (Rec D cs) ((_ , s) , p) =
ap (β-emb D cs (λ d → p (inl d))) (convert-unconvert cs (s , λ z → p (inr z)))
• γ-fix D cs s p
unconvert-mapArgs : (cs : ConstrArity {ℓ}) {C D : Type ℓ} (h : C → D)
(sp : Σ (Args cs (⊤ {ℓ})) (λ s → recPos cs s → C)) →
unconvert cs (fst sp , h ∘ snd sp)
≡ mapArgs cs h (unconvert cs sp)
unconvert-mapArgs Done h _ = refl
unconvert-mapArgs (Nonrec A k) h ((a , s) , p) =
ap (λ z → (a , z)) (unconvert-mapArgs (k a) h (s , p))
unconvert-mapArgs (Rec D cs) h ((_ , s) , p) =
ap (λ z → ((λ d → h (p (inl d))) , z))
(unconvert-mapArgs cs h (s , (λ z → p (inr z))))
convertIH : (cs : ConstrArity {ℓ}) {C : Type ℓ} {motive : C → Type ℓ}
(args : Args cs C) →
IHs cs motive args →
(z : recPos cs (fst (convert cs args))) →
motive (snd (convert cs args) z)
convertIH Done _ _ ()
convertIH (Nonrec A k) (a , args) ih z = convertIH (k a) args ih z
convertIH (Rec D cs) (r , args) (ih_h , ih_t) (inl d) = ih_h d
convertIH (Rec D cs) (r , args) (ih_h , ih_t) (inr z) = convertIH cs args ih_t z
triangle : {C : Type ℓ} (cs : ConstrArity {ℓ})
(sp : Σ (Args cs (⊤ {ℓ})) (λ s → recPos cs s → C)) →
unconvert-convert cs (unconvert cs sp)
≡ ap (unconvert cs) (convert-unconvert cs sp)
triangle Done (tt , p) = ! (ap-const (Σ-≡-intro refl (ext (λ ()))))
triangle (Nonrec A k) ((a , s) , p) =
ap (ap (λ z → (a , z))) (triangle (k a) (s , p))
• ! (ap-∘ (convert-unconvert (k a) (s , p)))
• ap-∘ (convert-unconvert (k a) (s , p))
triangle {C} (Rec D cs) ((shape0 , s) , p) =
ap (ap (λ z → ((λ d → p (inl d)) , z)))
(triangle cs (s , λ z → p (inr z)))
• ! (ap-∘ (convert-unconvert cs (s , λ z → p (inr z))))
• ap-∘ {f = unconvert (Rec D cs)} {g = β-emb D cs (λ d → p (inl d))}
(convert-unconvert cs (s , λ z → p (inr z)))
• ! •unitr
• ap (ap (unconvert (Rec D cs)) β-step •_) (! ap-γ-refl)
• ! (ap-• (unconvert (Rec D cs)) β-step γ-path)
where
β-step : β-emb D cs (λ d → p (inl d))
(convert cs (unconvert cs (s , λ z → p (inr z))))
≡ β-emb D cs (λ d → p (inl d)) (s , λ z → p (inr z))
β-step = ap (β-emb D cs (λ d → p (inl d)))
(convert-unconvert cs (s , λ z → p (inr z)))
γ-path : β-emb D cs (λ d → p (inl d)) (s , λ z → p (inr z))
≡ (((λ _ → tt) , s) , p)
γ-path = γ-fix D cs s p
ap-precomp-inl-refl :
ap (λ v → λ d → v (inl d)) (ext (pwr-of cs p)) ≡ refl
ap-precomp-inl-refl =
precomp-ext inl (pwr-of cs p)
• ! funext-refl
ap-snd-side-refl :
ap (λ v → unconvert cs (s , λ z → v (inr z))) (ext (pwr-of cs p))
≡ refl
ap-snd-side-refl =
ap-∘ (ext (pwr-of cs p))
• ap (ap (unconvert cs))
( ap-∘ (ext (pwr-of cs p))
• ap (ap (λ q → (s , q)))
( precomp-ext inr (pwr-of cs p)
• ! funext-refl))
collapse-Σ-product : {A : Type ℓ} {B : Type ℓ}
{a : A} {b : B}
{x : a ≡ a} {y : b ≡ b}
(q1 : x ≡ refl) (q2 : y ≡ refl) →
Σ-≡-intro {B = λ _ → B} x (tptConst x b • y) ≡ refl
collapse-Σ-product refl refl = refl
ap-γ-refl : ap (unconvert (Rec D cs)) γ-path ≡ refl
ap-γ-refl =
ap (ap (unconvert (Rec D cs))) (Σ-≡-intro-refl (ext (pwr-of cs p)))
• ! (ap-∘ {f = unconvert (Rec D cs)}
{g = λ v → (((λ _ → tt) , s) , v)} (ext (pwr-of cs p)))
• ap-Σ-const (λ v → λ d → v (inl d))
(λ v → unconvert cs (s , λ z → v (inr z)))
(ext (pwr-of cs p))
• collapse-Σ-product ap-precomp-inl-refl ap-snd-side-refl
convertIH-applyElim :
(cs : ConstrArity {ℓ}) {C : Type ℓ} {motive : C → Type ℓ}
(args : Args cs C) (elim : (x : C) → motive x) →
(z : recPos cs (fst (convert cs args))) →
convertIH cs args (mkIHs cs elim args) z
≡ elim (snd (convert cs args) z)
convertIH-applyElim Done _ _ ()
convertIH-applyElim (Nonrec A k) (a , args) elim z =
convertIH-applyElim (k a) args elim z
convertIH-applyElim (Rec D cs) (r , args) elim (inl d) = refl
convertIH-applyElim (Rec D cs) (r , args) elim (inr z) =
convertIH-applyElim cs args elim z
A : Type ℓ
A = Σ Op (λ c → Args (arity c) (⊤ {ℓ}))
B : A → Type ℓ
B (c , s) = recPos (arity c) s
wtypeSignature : Signature
wtypeSignature = WTypeSignature A B
convertArgs : (c : Op) → (Ty : Type ℓ) → Args (arity c) Ty → Args (Signature.arity wtypeSignature tt) Ty
convertArgs c Ty args =
let (s , p) = convert (arity c) args in ((c , s) , p , tt)
module _ {C : Type ℓ} (indAlg : IndAlg sig C) where
open IndAlg indAlg
wtypeConstr : ⊤ {ℓ} → Args (Signature.arity wtypeSignature tt) C → C
wtypeConstr _ ((c , s) , p , tt) = algebra c (unconvert (arity c) (s , p))
origMPOfWtypeMP : (motive : C → Type ℓ) →
Cases wtypeSignature C wtypeConstr motive →
Cases sig C algebra motive
origMPOfWtypeMP motive wmp c args ih =
tpt (λ z → motive (algebra c z)) (unconvert-convert (arity c) args)
(wmp tt ((c , fst (convert (arity c) args))
, snd (convert (arity c) args)
, tt)
(convertIH (arity c) args ih , tt))
wtypeInd : (motive : C → Type ℓ) →
Cases wtypeSignature C wtypeConstr motive →
(a : C) → motive a
wtypeInd motive wmp = ind motive (origMPOfWtypeMP motive wmp)
wtypeBeta : BetaLaw wtypeSignature wtypeInd
wtypeBeta motive wmp tt ((c , s) , p , tt) =
let sp' = convert (arity c) (unconvert (arity c) (s , p))
target = wmp tt ((c , fst sp') , snd sp' , tt)
((λ z → wtypeInd motive wmp (snd sp' z)) , tt)
in
beta motive (origMPOfWtypeMP motive wmp) c (unconvert (arity c) (s , p))
• ap (tpt (λ z → motive (algebra c z))
(unconvert-convert (arity c) (unconvert (arity c) (s , p))))
(ap (wmp tt ((c , fst sp') , snd sp' , tt))
(Σ-≡-intro (ext (convertIH-applyElim (arity c)
(unconvert (arity c) (s , p))
(wtypeInd motive wmp)))
refl))
• ap (λ q → tpt (λ z → motive (algebra c z)) q target)
(triangle (arity c) (s , p))
• tpt-along-q (convert-unconvert (arity c) (s , p))
where
tpt-along-q :
{sp sp' : Σ (Args (arity c) (⊤ {ℓ}))
(λ s → recPos (arity c) s → C)}
(q : sp' ≡ sp) →
tpt (motive ∘ algebra c) (ap (unconvert (arity c)) q)
(wmp tt ((c , fst sp') , snd sp' , tt)
((λ z → wtypeInd motive wmp (snd sp' z)) , tt))
≡ wmp tt ((c , fst sp) , snd sp , tt)
((λ z → wtypeInd motive wmp (snd sp z)) , tt)
tpt-along-q refl = refl
indAlgWtype : WTypeIndAlg A B C
indAlgWtype .IndAlg.algebra = wtypeConstr
indAlgWtype .IndAlg.ind = wtypeInd
indAlgWtype .IndAlg.beta = wtypeBeta
allIndAlgWTypeIndAlg : Σ (Type ℓ) (λ A → Σ (A → Type ℓ)
(λ B → WTypeIndAlg A B C))
allIndAlgWTypeIndAlg = (A , B , indAlgWtype)
module _ {C D : Type ℓ} (iC : IndAlg sig C) (iD : IndAlg sig D) where
foldW : C → D
foldW = IndAlg.fold (indAlgWtype iC) (wtypeConstr iD)
wtypeFold-hom : (c : Op) (args : Args (arity c) C) →
foldW (IndAlg.algebra iC c args)
≡ IndAlg.algebra iD c (mapArgs (arity c) foldW args)
wtypeFold-hom c args =
ap (foldW ∘ IndAlg.algebra iC c) (! (unconvert-convert (arity c) args))
• IndAlg.fold-β (indAlgWtype iC) (wtypeConstr iD) tt
((c , fst sp) , snd sp , tt)
• ap (IndAlg.algebra iD c) (unconvert-mapArgs (arity c) foldW sp)
• ap (IndAlg.algebra iD c ∘ mapArgs (arity c) foldW)
(unconvert-convert (arity c) args)
where
sp = convert (arity c) args
wtypeFoldAgree : (x : C) →
foldW x ≡ IndAlg.fold iC (IndAlg.algebra iD) x
wtypeFoldAgree = fold-unique iC (IndAlg.algebra iD) foldW wtypeFold-hom
module _ {C D : Type ℓ} (config : Config sig C D) where
open Config config
configWTypeConfig : WTypeConfig A B C D
configWTypeConfig = record
{ indAlgC = indAlgWtype indAlgC
; indAlgD = indAlgWtype indAlgD }
allConfigWTypeConfig : Σ (Type ℓ) (λ A → Σ (A → Type ℓ) (λ B → WTypeConfig A B C D))
allConfigWTypeConfig = (A , B , configWTypeConfig)
wtypeConfigEquivAgree-f :
_≃_.f (snd (configToEquiv configWTypeConfig))
≡ _≃_.f (snd (configToEquiv config))
wtypeConfigEquivAgree-f = ext (wtypeFoldAgree indAlgC indAlgD)
wtypeConfigEquivAgree-g :
_≃_.g (snd (configToEquiv configWTypeConfig))
≡ _≃_.g (snd (configToEquiv config))
wtypeConfigEquivAgree-g = ext (wtypeFoldAgree indAlgD indAlgC)