open import Categories.Category
open import Monad.Instance.Delay
open import Categories.Category.Cartesian using (Cartesian)
open import Categories.Category.Extensive using (Extensive)
open import Categories.Category.Extensive.Properties.Distributive
open import Categories.Object.NaturalNumbers.Parametrized
open import Level using (_⊔_)
open import Data.Product using (Σ-syntax; _,_; proj₁; proj₂)
import Categories.Morphism as M
import Categories.Morphism.Reasoning as MR
import Categories.Morphism.Properties as MP
module Monad.Instance.Delay.LPO {o ℓ e} {C : Category o ℓ e}
(extensive : Extensive C) (cartesian : Cartesian C)
(D : DelayM (Extensive.cocartesian extensive))
(PNNO : ParametrizedNNO C cartesian) where
open Category C
private distributive = Extensive×Cartesian⇒Distributive C extensive cartesian
open import Category.Distributive.Helper distributive hiding (cartesian)
open Bundles
open DelayM D
open HomReasoning
open Equiv
open D-Monad
open D-Kleisli
open Later∘Extend
open Coit
open M C
open MR C
open MP C
open ParametrizedNNO PNNO renaming (unique to pnno-unique)
open import Monad.Instance.Delay.Iota distributive D PNNO
open import Monad.Instance.Delay.Pullbacks extensive cartesian D
open import Monad.Instance.Delay.Cartesian extensive cartesian D using (D-preserves-pullback)
open import Categories.Category.Cocartesian.Monoidal
open CocartesianMonoidal cocartesian using (⊥+A≅A)
open import Monad.Instance.Delay.Zip distributive D
∞ : ∀ {X} → ⊤ ⇒ D₀ X
∞ = coit i₂
∞-commutes : ∀ {X} → out ∘ ∞ {X} ≈ (id +₁ ∞) ∘ i₂
∞-commutes = coit-commutes i₂
∞-later : ∀ {X} → ∞ {X} ≈ later ∘ ∞
∞-later = begin
∞ ≈⟨ cancelˡ out⁻¹∘out ⟨
out⁻¹ ∘ out ∘ ∞ ≈⟨ refl⟩∘⟨ ∞-commutes ⟩
out⁻¹ ∘ (id +₁ ∞) ∘ i₂ ≈⟨ pushʳ inject₂ ⟩
later ∘ ∞ ∎
∞-natural : ∀ {X Y} (f : X ⇒ Y) → D.F.₁ f ∘ ∞ {X} ≈ ∞ {Y}
∞-natural f = sym (coit-unique i₂ (D.F.₁ f ∘ ∞) (begin
out ∘ D.F.₁ f ∘ ∞ ≈⟨ pullˡ (D₁-commutes f) ⟩
((f +₁ D.F.₁ f) ∘ out) ∘ ∞ ≈⟨ pullʳ ∞-commutes ⟩
(f +₁ D.F.₁ f) ∘ (id +₁ ∞) ∘ i₂ ≈⟨ pullˡ (+₁∘+₁ ○ +₁-cong₂ identityʳ refl) ⟩
(f +₁ (D.F.₁ f ∘ ∞)) ∘ i₂ ≈⟨ inject₂ ○ sym inject₂ ⟩
(id +₁ (D.F.₁ f ∘ ∞)) ∘ i₂ ∎))
copair : ∀ {A B Z} → A ⇒ Z → B ⇒ Z → A + B ⇒ Z
copair f g = [ f , g ]
[ι,∞] : ∀ {X} → (X × N) + ⊤ ⇒ D₀ X
[ι,∞] = copair ι ∞
+₁-iso : ∀ {A B A' B'} {f : A ⇒ A'} {g : B ⇒ B'} → IsIso f → IsIso g → IsIso (f +₁ g)
+₁-iso {f = f} {g = g} fi gi .M.IsIso.inv = IsIso.inv fi +₁ IsIso.inv gi
+₁-iso {f = f} {g = g} fi gi .M.IsIso.iso .M.Iso.isoˡ = begin
(IsIso.inv fi +₁ IsIso.inv gi) ∘ (f +₁ g) ≈⟨ +₁∘+₁ ⟩
(IsIso.inv fi ∘ f) +₁ (IsIso.inv gi ∘ g) ≈⟨ +₁-cong₂ (Iso.isoˡ (IsIso.iso fi)) (Iso.isoˡ (IsIso.iso gi)) ⟩
id +₁ id ≈⟨ id+₁id ⟩
id ∎
+₁-iso {f = f} {g = g} fi gi .M.IsIso.iso .M.Iso.isoʳ = begin
(f +₁ g) ∘ (IsIso.inv fi +₁ IsIso.inv gi) ≈⟨ +₁∘+₁ ⟩
(f ∘ IsIso.inv fi) +₁ (g ∘ IsIso.inv gi) ≈⟨ +₁-cong₂ (Iso.isoʳ (IsIso.iso fi)) (Iso.isoʳ (IsIso.iso gi)) ⟩
id +₁ id ≈⟨ id+₁id ⟩
id ∎
open import Categories.Diagram.Pullback C using (IsPullback; Pullback)
open import Categories.Object.Coproduct C using (IsCoproduct)
open import Categories.Category.Extensive.Properties C as EP
pb-post-mono : ∀ {P A B Q R} {p₁ : P ⇒ A} {p₂ : P ⇒ B} {f : A ⇒ Q} {g : B ⇒ Q} {m : Q ⇒ R}
→ Mono m → IsPullback p₁ p₂ f g → IsPullback p₁ p₂ (m ∘ f) (m ∘ g)
pb-post-mono m-mono pb .IsPullback.commute = extendˡ (IsPullback.commute pb)
pb-post-mono m-mono pb .IsPullback.universal = λ eq → IsPullback.universal pb (m-mono _ _ (sym-assoc ○ eq ○ assoc))
pb-post-mono m-mono pb .IsPullback.p₁∘universal≈h₁ = IsPullback.p₁∘universal≈h₁ pb
pb-post-mono m-mono pb .IsPullback.p₂∘universal≈h₂ = IsPullback.p₂∘universal≈h₂ pb
pb-post-mono m-mono pb .IsPullback.unique-diagram = IsPullback.unique-diagram pb
IsPullback-resp-≈ : ∀ {P A B Q} {p₁ : P ⇒ A} {p₂ : P ⇒ B} {f f' : A ⇒ Q} {g g' : B ⇒ Q}
→ f ≈ f' → g ≈ g' → IsPullback p₁ p₂ f g → IsPullback p₁ p₂ f' g'
IsPullback-resp-≈ ef eg pb .IsPullback.commute = ∘-resp-≈ˡ (sym ef) ○ IsPullback.commute pb ○ ∘-resp-≈ˡ eg
IsPullback-resp-≈ ef eg pb .IsPullback.universal = λ eq → IsPullback.universal pb ( ∘-resp-≈ˡ ef ○ eq ○ (∘-resp-≈ˡ (sym eg)) )
IsPullback-resp-≈ ef eg pb .IsPullback.p₁∘universal≈h₁ = IsPullback.p₁∘universal≈h₁ pb
IsPullback-resp-≈ ef eg pb .IsPullback.p₂∘universal≈h₂ = IsPullback.p₂∘universal≈h₂ pb
IsPullback-resp-≈ ef eg pb .IsPullback.unique-diagram = IsPullback.unique-diagram pb
pb-vertex-iso : ∀ {V V' A B Q} {p₁ : V ⇒ A} {p₂ : V ⇒ B} {f : A ⇒ Q} {g : B ⇒ Q} {σ : V' ⇒ V}
→ IsIso σ → IsPullback p₁ p₂ f g → IsPullback (p₁ ∘ σ) (p₂ ∘ σ) f g
pb-vertex-iso {p₁ = p₁} {p₂} {σ = σ} σiso pb .IsPullback.commute = extendʳ (IsPullback.commute pb)
pb-vertex-iso {p₁ = p₁} {p₂} {σ = σ} σiso pb .IsPullback.universal = λ eq → IsIso.inv σiso ∘ IsPullback.universal pb eq
pb-vertex-iso {p₁ = p₁} {p₂} {σ = σ} σiso pb .IsPullback.p₁∘universal≈h₁ = cancelInner (Iso.isoʳ (IsIso.iso σiso)) ○ IsPullback.p₁∘universal≈h₁ pb
pb-vertex-iso {p₁ = p₁} {p₂} {σ = σ} σiso pb .IsPullback.p₂∘universal≈h₂ = cancelInner (Iso.isoʳ (IsIso.iso σiso)) ○ IsPullback.p₂∘universal≈h₂ pb
pb-vertex-iso {p₁ = p₁} {p₂} {σ = σ} σiso pb .IsPullback.unique-diagram = λ eq₁ eq₂ → Iso⇒Mono (IsIso.iso σiso) _ _
(IsPullback.unique-diagram pb (sym-assoc ○ eq₁ ○ assoc) (sym-assoc ○ eq₂ ○ assoc))
pb-cospan-iso : ∀ {V A B B' Q} {p₁ : V ⇒ A} {p₂ : V ⇒ B} {f : A ⇒ Q} {g : B ⇒ Q} {m : B' ⇒ B}
→ (miso : IsIso m) → IsPullback p₁ p₂ f g → IsPullback p₁ (IsIso.inv miso ∘ p₂) f (g ∘ m)
pb-cospan-iso {p₂ = p₂} {g = g} {m = m} miso pb .IsPullback.commute = IsPullback.commute pb ○ sym (cancelInner (Iso.isoʳ (IsIso.iso miso)))
pb-cospan-iso {p₂ = p₂} {g = g} {m = m} miso pb .IsPullback.universal = λ eq → IsPullback.universal pb (eq ○ assoc)
pb-cospan-iso {p₂ = p₂} {g = g} {m = m} miso pb .IsPullback.p₁∘universal≈h₁ = IsPullback.p₁∘universal≈h₁ pb
pb-cospan-iso {p₂ = p₂} {g = g} {m = m} miso pb .IsPullback.p₂∘universal≈h₂ = pullʳ (IsPullback.p₂∘universal≈h₂ pb) ○ cancelˡ (Iso.isoˡ (IsIso.iso miso))
pb-cospan-iso {p₂ = p₂} {g = g} {m = m} miso pb .IsPullback.unique-diagram = λ eq₁ eq₂ → IsPullback.unique-diagram pb eq₁
(Iso⇒Mono (Iso-swap (IsIso.iso miso)) _ _ (sym-assoc ○ eq₂ ○ assoc))
later∘ι̂ : later ∘ ι̂ ≈ ι̂ ∘ s
later∘ι̂ = begin
later ∘ ι ∘ ⟨ ! , id ⟩ ≈⟨ pushˡ ι-succ ⟨
(ι ∘ (id ×₁ s)) ∘ ⟨ ! , id ⟩ ≈⟨ extendˡ (×₁∘⟨⟩ ○ ⟨⟩-cong₂ !-unique₂ id-comm ○ sym ⟨⟩∘) ⟩
ι̂ ∘ s ∎
now∘! : ∀ {A} → now ∘ ! {A} ≈ ι̂ ∘ z ∘ !
now∘! = begin
now ∘ ! ≈⟨ pullˡ ι-zero ⟨
ι ∘ ⟨ id , z ∘ ! ⟩ ∘ ! ≈⟨ pushʳ (⟨⟩∘ ○ ⟨⟩-cong₂ !-unique₂ (pullʳ !-unique₂ ○ sym identityˡ) ○ sym ⟨⟩∘) ⟩
ι̂ ∘ z ∘ ! ∎
from-⊥-obj-unique : ∀ {A S} → A ≅ ⊥ → (p q : A ⇒ S) → p ≈ q
from-⊥-obj-unique A≅⊥ p q = begin
p ≈⟨ introʳ (_≅_.isoˡ A≅⊥) ⟩
p ∘ _≅_.to A≅⊥ ∘ _≅_.from A≅⊥ ≈⟨ pullˡ (¡-unique₂ _ _) ⟩
¡ ∘ _≅_.from A≅⊥ ≈⟨ pullˡ (¡-unique₂ _ _) ⟨
q ∘ _≅_.to A≅⊥ ∘ _≅_.from A≅⊥ ≈⟨ elimʳ (_≅_.isoˡ A≅⊥) ⟩
q ∎
coproduct-inj₂-iso : ∀ {A B S} {f : A ⇒ S} {g : B ⇒ S}
→ IsCoproduct f g → A ≅ ⊥ → IsIso g
coproduct-inj₂-iso {A}{B}{S}{f}{g} cp A≅⊥ = record
{ inv = CP.[ ¡ ∘ _≅_.from A≅⊥ , id ]
; iso = record
{ isoˡ = CP.inject₂
; isoʳ = sym (CP.unique eq-f eq-g) ○ CP.unique identityˡ identityˡ
}
}
where
module CP = IsCoproduct cp
eq-f : (g ∘ CP.[ ¡ ∘ _≅_.from A≅⊥ , id ]) ∘ f ≈ f
eq-f = pullʳ CP.inject₁ ○ from-⊥-obj-unique A≅⊥ _ _
eq-g : (g ∘ CP.[ ¡ ∘ _≅_.from A≅⊥ , id ]) ∘ g ≈ g
eq-g = pullʳ CP.inject₂ ○ identityʳ
IsCoproduct-resp-≈ : ∀ {A B S} {f f' : A ⇒ S} {g g' : B ⇒ S} → f ≈ f' → g ≈ g' → IsCoproduct f g → IsCoproduct f' g'
IsCoproduct-resp-≈ {f' = f'}{g' = g'} ef eg cp = record
{ [_,_] = CP.[_,_]
; inject₁ = ∘-resp-≈ʳ (sym ef) ○ CP.inject₁
; inject₂ = ∘-resp-≈ʳ (sym eg) ○ CP.inject₂
; unique = λ eq₁ eq₂ → CP.unique (∘-resp-≈ʳ ef ○ eq₁) (∘-resp-≈ʳ eg ○ eq₂)
}
where module CP = IsCoproduct cp
IsCoproduct-precompose-iso : ∀ {A B S A' B'} {f : A ⇒ S} {g : B ⇒ S} (α : A' ⇒ A) (β : B' ⇒ B)
→ IsCoproduct f g → IsIso α → IsIso β → IsCoproduct (f ∘ α) (g ∘ β)
IsCoproduct-precompose-iso {f = f}{g} α β cp αiso βiso = record
{ [_,_] = λ p q → CP.[ p ∘ IsIso.inv αiso , q ∘ IsIso.inv βiso ]
; inject₁ = pullˡ CP.inject₁ ○ cancelʳ (Iso.isoˡ (IsIso.iso αiso))
; inject₂ = pullˡ CP.inject₂ ○ cancelʳ (Iso.isoˡ (IsIso.iso βiso))
; unique = λ {_}{h}{p}{q} eq₁ eq₂ → CP.unique
(pushʳ (sym (cancelʳ (Iso.isoʳ (IsIso.iso αiso)))) ○ ∘-resp-≈ˡ eq₁)
(pushʳ (sym (cancelʳ (Iso.isoʳ (IsIso.iso βiso)))) ○ ∘-resp-≈ˡ eq₂)
}
where module CP = IsCoproduct cp
two-pb-iso : ∀ {P P' A B Q} {p₁ : P ⇒ A} {p₂ : P ⇒ B} {p₁' : P' ⇒ A} {p₂' : P' ⇒ B} {f : A ⇒ Q} {g : B ⇒ Q}
→ (pb₁ : IsPullback p₁ p₂ f g) (pb₂ : IsPullback p₁' p₂' f g)
→ IsIso (IsPullback.universal pb₁ (IsPullback.commute pb₂))
two-pb-iso pb₁ pb₂ .M.IsIso.inv = IsPullback.universal pb₂ (IsPullback.commute pb₁)
two-pb-iso pb₁ pb₂ .M.IsIso.iso .M.Iso.isoˡ = IsPullback.unique-diagram pb₂
(pullˡ (IsPullback.p₁∘universal≈h₁ pb₂) ○ IsPullback.p₁∘universal≈h₁ pb₁ ○ sym identityʳ)
(pullˡ (IsPullback.p₂∘universal≈h₂ pb₂) ○ IsPullback.p₂∘universal≈h₂ pb₁ ○ sym identityʳ)
two-pb-iso pb₁ pb₂ .M.IsIso.iso .M.Iso.isoʳ = IsPullback.unique-diagram pb₁
(pullˡ (IsPullback.p₁∘universal≈h₁ pb₁) ○ IsPullback.p₁∘universal≈h₁ pb₂ ○ sym identityʳ)
(pullˡ (IsPullback.p₂∘universal≈h₂ pb₁) ○ IsPullback.p₂∘universal≈h₂ pb₂ ○ sym identityʳ)
IsCoproduct⇒iso : ∀ {A B S} {f : A ⇒ S} {g : B ⇒ S} → IsCoproduct f g → IsIso (copair f g)
IsCoproduct⇒iso {f = f}{g = g} cp = record
{ inv = CP.[ i₁ , i₂ ]
; iso = record
{ isoˡ = sym ([]-unique (pullʳ inject₁ ○ CP.inject₁) (pullʳ inject₂ ○ CP.inject₂)) ○ +-η
; isoʳ = sym (CP.unique (pullʳ CP.inject₁ ○ inject₁) (pullʳ CP.inject₂ ○ inject₂)) ○ CP.unique identityˡ identityˡ
}
}
where module CP = IsCoproduct cp
iso⇒IsCoproduct : ∀ {A B S} {f : A ⇒ S} {g : B ⇒ S} → IsIso (copair f g) → IsCoproduct f g
iso⇒IsCoproduct {f = f}{g = g} miso = record
{ [_,_] = λ h₁ h₂ → [ h₁ , h₂ ] ∘ m⁻¹
; inject₁ = pullʳ m⁻¹∘f≈i₁ ○ inject₁
; inject₂ = pullʳ m⁻¹∘g≈i₂ ○ inject₂
; unique = λ {_}{u}{h₁}{h₂} u∘f≈h₁ u∘g≈h₂ → ∘-resp-≈ˡ ([]-unique (pullʳ inject₁ ○ u∘f≈h₁) (pullʳ inject₂ ○ u∘g≈h₂))
○ cancelʳ (Iso.isoʳ (IsIso.iso miso))
}
where
m⁻¹ = IsIso.inv miso
m⁻¹∘f≈i₁ = pushʳ (sym inject₁) ○ elimˡ (Iso.isoˡ (IsIso.iso miso))
m⁻¹∘g≈i₂ = pushʳ (sym inject₂) ○ elimˡ (Iso.isoˡ (IsIso.iso miso))
i₂-factors : ∀ {Z A B} (k : Z ⇒ A + B) → (Pullback.P (Extensive.pullback₁ extensive k) ⇒ ⊥) → Σ[ w ∈ (Z ⇒ B) ] (k ≈ i₂ ∘ w)
i₂-factors {Z}{A}{B} k P₁⇒⊥ = w , k≈i₂w
where
pb₂ = Extensive.pullback₂ extensive k
cp : IsCoproduct (Pullback.p₁ (Extensive.pullback₁ extensive k)) (Pullback.p₁ pb₂)
cp = Extensive.pullback-of-cp-is-cp extensive k
P₁≅⊥ : Pullback.P (Extensive.pullback₁ extensive k) ≅ ⊥
P₁≅⊥ = record { from = P₁⇒⊥ ; to = IsIso.inv f⊥ ; iso = IsIso.iso f⊥ }
where f⊥ = EP.to-⊥-is-iso extensive P₁⇒⊥
a₂-iso : IsIso (Pullback.p₁ pb₂)
a₂-iso = coproduct-inj₂-iso cp P₁≅⊥
w : Z ⇒ B
w = Pullback.p₂ pb₂ ∘ IsIso.inv a₂-iso
k≈i₂w : k ≈ i₂ ∘ w
k≈i₂w = introʳ (Iso.isoʳ (IsIso.iso a₂-iso)) ○ extendʳ (Pullback.commute pb₂)
LPO : Set (o ⊔ ℓ ⊔ e)
LPO = Σ[ I ∈ Obj ] Σ[ i ∈ (I ⇒ D.F.₀ ⊤) ] IsIso (copair ι̂ i)
N×X+1⇒LPO : IsIso ([ι,∞] {⊤}) → LPO
N×X+1⇒LPO given = ⊤ , ∞ , record { inv = (π₂ +₁ id) ∘ IsIso.inv given ; iso = iso[ι̂,∞] }
where
⟨!,id⟩-iso : IsIso ⟨ ! , id ⟩
⟨!,id⟩-iso = record { inv = π₂ ; iso = Iso-swap (_≅_.iso ⊤×A≅A) }
g₀-iso : IsIso (⟨ ! , id ⟩ +₁ id)
g₀-iso = +₁-iso ⟨!,id⟩-iso id-is-iso
eq : copair ι ∞ ∘ (⟨ ! , id ⟩ +₁ id) ≈ copair ι̂ ∞
eq = []∘+₁ ○ []-cong₂ refl identityʳ
iso[ι̂,∞] : Iso (copair ι̂ ∞) ((π₂ +₁ id) ∘ IsIso.inv given)
iso[ι̂,∞] = Iso-resp-≈ (Iso-∘ (IsIso.iso g₀-iso) (IsIso.iso given)) eq refl
!-coalg-morph : ∀ {A} (α : A ⇒ ⊥ + A) → i₂ ∘ ! ≈ (id +₁ !) ∘ α
!-coalg-morph {A} α = Iso⇒Mono (_≅_.iso (⊥+A≅A {⊤})) (i₂ ∘ !) ((id +₁ !) ∘ α) !-unique₂
D∅≅1 : D.F.₀ ⊥ ≅ ⊤
D∅≅1 = record
{ from = !
; to = ∞
; iso = record
{ isoˡ = ∞∘!≈id
; isoʳ = sym (!-unique (! ∘ ∞)) ○ !-unique id
}
}
where
eq₁ : out ∘ (∞ ∘ !) ≈ (id +₁ (∞ ∘ !)) ∘ out
eq₁ = begin
out ∘ ∞ ∘ ! ≈⟨ pullˡ ∞-commutes ⟩
((id +₁ ∞) ∘ i₂) ∘ ! ≈⟨ extendˡ (!-coalg-morph out) ⟩
((id +₁ ∞) ∘ (id +₁ !)) ∘ out ≈⟨ (+₁∘+₁ ○ +₁-cong₂ identity² refl) ⟩∘⟨refl ⟩
(id +₁ (∞ ∘ !)) ∘ out ∎
eq₂ : out ∘ id ≈ (id +₁ id) ∘ out
eq₂ = identityʳ ○ sym (elimˡ id+₁id)
∞∘!≈id : ∞ ∘ ! ≈ id
∞∘!≈id = sym (coit-unique out (∞ ∘ !) eq₁) ○ coit-unique out id eq₂
LPO⇒N×X+1 : LPO → ∀ {X} → IsIso ([ι,∞] {X})
LPO⇒N×X+1 (I , i , iso) {X} = IsCoproduct⇒iso IsCop-ι∞
where
μ : N + I ⇒ D.F.₀ ⊤
μ = copair ι̂ i
μ-mono : Mono μ
μ-mono = Iso⇒Mono (IsIso.iso iso)
ι̂-i-disjoint : IsPullback (¡ {N}) (¡ {I}) ι̂ i
ι̂-i-disjoint = IsPullback-resp-≈ inject₁ inject₂ (pb-post-mono μ-mono (Extensive.disjoint extensive))
μ⁻¹ : D₀ ⊤ ⇒ N + I
μ⁻¹ = IsIso.inv iso
pb₁-out = Extensive.pullback₁ extensive (out ∘ i)
clash-out : Pullback.P pb₁-out ⇒ ⊥
clash-out = IsPullback.universal ι̂-i-disjoint cone-out
where
a₁ = Pullback.p₁ pb₁-out
b₁ = Pullback.p₂ pb₁-out
cone-out : ι̂ ∘ z ∘ ! ≈ i ∘ a₁
cone-out = begin
ι̂ ∘ z ∘ ! ≈⟨ now∘! ⟨
now ∘ ! ≈⟨ refl⟩∘⟨ !-unique₂ ⟩
now ∘ b₁ ≈⟨ pushʳ (sym-assoc ○ Pullback.commute pb₁-out) ⟨
out⁻¹ ∘ out ∘ i ∘ a₁ ≈⟨ cancelˡ out⁻¹∘out ⟩
i ∘ a₁ ∎
w : I ⇒ D.F.₀ ⊤
w = proj₁ (i₂-factors (out ∘ i) clash-out)
out∘i≈i₂w : out ∘ i ≈ i₂ ∘ w
out∘i≈i₂w = proj₂ (i₂-factors (out ∘ i) clash-out)
i≈later∘w : i ≈ later ∘ w
i≈later∘w = sym (cancelˡ out⁻¹∘out) ○ pushʳ out∘i≈i₂w
μ⁻¹-mono : Mono μ⁻¹
μ⁻¹-mono = Iso⇒Mono (Iso-swap (IsIso.iso iso))
μ⁻¹∘ι̂ : μ⁻¹ ∘ ι̂ ≈ i₁
μ⁻¹∘ι̂ = (refl⟩∘⟨ sym inject₁) ○ cancelˡ (Iso.isoˡ (IsIso.iso iso))
pb₁-w = Extensive.pullback₁ extensive (μ⁻¹ ∘ w)
clash-w : Pullback.P pb₁-w ⇒ ⊥
clash-w = IsPullback.universal ι̂-i-disjoint cone-w
where
a = Pullback.p₁ pb₁-w
b = Pullback.p₂ pb₁-w
w∘a≈ι̂∘b : w ∘ a ≈ ι̂ ∘ b
w∘a≈ι̂∘b = μ⁻¹-mono (w ∘ a) (ι̂ ∘ b) (begin
μ⁻¹ ∘ w ∘ a ≈⟨ sym-assoc ○ Pullback.commute pb₁-w ⟩
i₁ ∘ b ≈⟨ pullˡ μ⁻¹∘ι̂ ⟨
μ⁻¹ ∘ ι̂ ∘ b ∎)
cone-w : ι̂ ∘ s ∘ b ≈ i ∘ a
cone-w = begin
ι̂ ∘ s ∘ b ≈⟨ extendʳ later∘ι̂ ⟨
later ∘ ι̂ ∘ b ≈⟨ refl⟩∘⟨ w∘a≈ι̂∘b ⟨
later ∘ w ∘ a ≈⟨ pushˡ i≈later∘w ⟨
i ∘ a ∎
v : I ⇒ I
v = proj₁ (i₂-factors (μ⁻¹ ∘ w) clash-w)
μ⁻¹w≈i₂v : μ⁻¹ ∘ w ≈ i₂ ∘ v
μ⁻¹w≈i₂v = proj₂ (i₂-factors (μ⁻¹ ∘ w) clash-w)
w≈i∘v : w ≈ i ∘ v
w≈i∘v = introˡ (Iso.isoʳ (IsIso.iso iso)) ○ pullʳ μ⁻¹w≈i₂v ○ pullˡ inject₂
out∘i≈i₂iv : out ∘ i ≈ (id +₁ i) ∘ (i₂ ∘ v)
out∘i≈i₂iv = begin
out ∘ i ≈⟨ out∘i≈i₂w ⟩
i₂ ∘ w ≈⟨ refl⟩∘⟨ w≈i∘v ⟩
i₂ ∘ i ∘ v ≈⟨ extendʳ inject₂ ⟨
(id +₁ i) ∘ i₂ ∘ v ∎
i≈∞! : i ≈ ∞ ∘ !
i≈∞! = sym (coit-unique (i₂ ∘ v) i out∘i≈i₂iv) ○ coit-unique (i₂ ∘ v) (∞ ∘ !) eq∞
where
eq∞ : out ∘ (∞ ∘ !) ≈ (id +₁ (∞ ∘ !)) ∘ (i₂ ∘ v)
eq∞ = begin
out ∘ ∞ ∘ ! ≈⟨ extendʳ (∞-commutes ○ inject₂) ⟩
i₂ ∘ ∞ ∘ ! ≈⟨ refl⟩∘⟨ refl⟩∘⟨ !-unique₂ ⟩
i₂ ∘ ∞ ∘ ! ∘ v ≈⟨ refl⟩∘⟨ sym-assoc ⟩
i₂ ∘ (∞ ∘ !) ∘ v ≈⟨ extendʳ inject₂ ⟨
(id +₁ (∞ ∘ !)) ∘ i₂ ∘ v ∎
i-mono : Mono i
i-mono g h eq = Extensive.pullback₂-is-mono extensive g h
(μ-mono (i₂ ∘ g) (i₂ ∘ h) (pullˡ inject₂ ○ eq ○ sym (pullˡ inject₂)))
I-subterminal : ∀ {A} (g h : A ⇒ I) → g ≈ h
I-subterminal g h = i-mono g h (begin
i ∘ g ≈⟨ pushˡ i≈∞! ⟩
∞ ∘ ! ∘ g ≈⟨ refl⟩∘⟨ !-unique₂ ⟩
∞ ∘ ! ∘ h ≈⟨ pushˡ i≈∞! ⟨
i ∘ h ∎)
pb∞ = Extensive.pullback₁ extensive (μ⁻¹ ∘ ∞ {⊤})
clash∞ : Pullback.P pb∞ ⇒ ⊥
clash∞ = π₁ ∘ IsPullback.universal (ι-nat-pullback PNNO !) cone∞
where
a = Pullback.p₁ pb∞
b = Pullback.p₂ pb∞
∞∘a≈ι̂∘b : ∞ {⊤} ∘ a ≈ ι̂ ∘ b
∞∘a≈ι̂∘b = μ⁻¹-mono (∞ ∘ a) (ι̂ ∘ b) (begin
μ⁻¹ ∘ ∞ ∘ a ≈⟨ sym-assoc ○ Pullback.commute pb∞ ⟩
i₁ ∘ b ≈⟨ pullˡ μ⁻¹∘ι̂ ⟨
μ⁻¹ ∘ ι̂ ∘ b ∎)
cone∞ : D.F.₁ ! ∘ (∞ {⊥} ∘ a) ≈ ι ∘ (⟨ ! , id ⟩ ∘ b)
cone∞ = pullˡ (∞-natural !) ○ ∞∘a≈ι̂∘b ○ assoc
point : ⊤ ⇒ I
point = proj₁ (i₂-factors (μ⁻¹ ∘ ∞ {⊤}) clash∞)
I≅⊤ : I ≅ ⊤
I≅⊤ = record
{ from = !
; to = point
; iso = record { isoˡ = I-subterminal (point ∘ !) id ; isoʳ = !-unique₂ }
}
point-iso : IsIso point
point-iso = record { inv = ! ; iso = Iso-swap (_≅_.iso I≅⊤) }
i∘point≈∞ : i ∘ point ≈ ∞ {⊤}
i∘point≈∞ = pushˡ (sym inject₂) ○ (refl⟩∘⟨ sym (proj₂ (i₂-factors (μ⁻¹ ∘ ∞ {⊤}) clash∞)))
○ cancelˡ (Iso.isoʳ (IsIso.iso iso))
ν-iso : IsIso (copair ι̂ (∞ {⊤}))
ν-iso = record
{ inv = IsIso.inv (+₁-iso id-is-iso point-iso) ∘ μ⁻¹
; iso = Iso-resp-≈ (Iso-∘ (IsIso.iso (+₁-iso id-is-iso point-iso)) (IsIso.iso iso))
([]∘+₁ ○ []-cong₂ identityʳ i∘point≈∞) refl
}
D⊤-coproduct : IsCoproduct ι̂ (∞ {⊤})
D⊤-coproduct = iso⇒IsCoproduct ν-iso
νinv = IsIso.inv ν-iso
Dfun = D₁ (! {X})
pb₁ = Extensive.pullback₁ extensive (νinv ∘ Dfun)
pb₂ = Extensive.pullback₂ extensive (νinv ∘ Dfun)
q₁ = Pullback.p₁ pb₁
q₂ = Pullback.p₁ pb₂
DX-coproduct : IsCoproduct q₁ q₂
DX-coproduct = Extensive.pullback-of-cp-is-cp extensive (νinv ∘ Dfun)
ν-mono = Iso⇒Mono (IsIso.iso ν-iso)
νk≈D : copair ι̂ (∞ {⊤}) ∘ νinv ∘ Dfun ≈ Dfun
νk≈D = cancelˡ (Iso.isoʳ (IsIso.iso ν-iso))
Q₁-pb : IsPullback q₁ (Pullback.p₂ pb₁) Dfun ι̂
Q₁-pb = IsPullback-resp-≈ νk≈D inject₁ (pb-post-mono ν-mono (Pullback.isPullback pb₁))
⟨!,id⟩-iso : IsIso (⟨ ! , id {N} ⟩)
⟨!,id⟩-iso = record { inv = π₂ ; iso = Iso-swap (_≅_.iso ⊤×A≅A) }
ιpb : IsPullback ι (IsIso.inv ⟨!,id⟩-iso ∘ (! ×₁ id)) Dfun ι̂
ιpb = pb-cospan-iso ⟨!,id⟩-iso (ι-nat-pullback PNNO !)
α₁-iso = two-pb-iso Q₁-pb ιpb
Q₂-pb : IsPullback q₂ (Pullback.p₂ pb₂) Dfun (∞ {⊤})
Q₂-pb = IsPullback-resp-≈ νk≈D inject₂ (pb-post-mono ν-mono (Pullback.isPullback pb₂))
Q₂ = Pullback.P pb₂
q₂-mono : Mono q₂
q₂-mono g h eq = Extensive.pullback₂-is-mono extensive g h
(Iso⇒Mono (IsIso.iso (IsCoproduct⇒iso DX-coproduct)) (i₂ ∘ g) (i₂ ∘ h)
(pullˡ inject₂ ○ eq ○ sym (pullˡ inject₂)))
D!q₂≈∞! : Dfun ∘ q₂ ≈ ∞ {⊤} ∘ !
D!q₂≈∞! = IsPullback.commute Q₂-pb ○ (refl⟩∘⟨ !-unique₂)
gid : (! +₁ Dfun) ∘ out ∘ q₂ ≈ i₂ ∘ ∞ {⊤} ∘ !
gid = begin
(! +₁ Dfun) ∘ out ∘ q₂ ≈⟨ extendʳ (D₁-commutes !) ⟨
out ∘ Dfun ∘ q₂ ≈⟨ refl⟩∘⟨ D!q₂≈∞! ⟩
out ∘ ∞ {⊤} ∘ ! ≈⟨ extendʳ (∞-commutes ○ inject₂) ⟩
i₂ ∘ ∞ ∘ ! ∎
pb₁-q₂ = Extensive.pullback₁ extensive (out ∘ q₂)
clash-q₂ : Pullback.P pb₁-q₂ ⇒ ⊥
clash-q₂ = IsPullback.universal (Extensive.disjoint extensive) cone-q₂
where
a = Pullback.p₁ pb₁-q₂
b = Pullback.p₂ pb₁-q₂
+i₁ : (! +₁ Dfun) ∘ i₁ {X} {D₀ X} ≈ i₁ {⊤} {D₀ ⊤} ∘ ! {X}
+i₁ = +₁∘i₁
cone-q₂ : i₁ {⊤} {D₀ ⊤} ∘ ! ≈ i₂ ∘ (∞ {⊤} ∘ ! ∘ a)
cone-q₂ = ⟺ (begin
i₂ ∘ (∞ {⊤} ∘ ! ∘ a) ≈⟨ refl⟩∘⟨ sym-assoc ⟩
i₂ ∘ (∞ {⊤} ∘ !) ∘ a ≈⟨ extendʳ gid ⟨
(! +₁ Dfun) ∘ (out ∘ q₂) ∘ a ≈⟨ refl⟩∘⟨ Pullback.commute pb₁-q₂ ⟩
(! +₁ Dfun) ∘ i₁ ∘ b ≈⟨ extendʳ +i₁ ⟩
i₁ ∘ ! ∘ b ≈⟨ refl⟩∘⟨ !-unique₂ ⟨
i₁ {⊤} {D₀ ⊤} ∘ ! ∎)
w₂ : Q₂ ⇒ D₀ X
w₂ = proj₁ (i₂-factors (out ∘ q₂) clash-q₂)
out∘q₂≈i₂w₂ : out ∘ q₂ ≈ i₂ ∘ w₂
out∘q₂≈i₂w₂ = proj₂ (i₂-factors (out ∘ q₂) clash-q₂)
D!w₂≈∞! : Dfun ∘ w₂ ≈ ∞ {⊤} ∘ !
D!w₂≈∞! = Extensive.pullback₂-is-mono extensive _ _ (⟺ (begin
i₂ ∘ ∞ {⊤} ∘ ! ≈⟨ gid ⟨
(! +₁ Dfun) ∘ out ∘ q₂ ≈⟨ refl⟩∘⟨ out∘q₂≈i₂w₂ ⟩
(! +₁ Dfun) ∘ i₂ ∘ w₂ ≈⟨ extendʳ +i₂ ⟩
i₂ ∘ Dfun ∘ w₂ ∎))
where
+i₂ : (! +₁ Dfun) ∘ i₂ {X} {D₀ X} ≈ i₂ {⊤} {D₀ ⊤} ∘ Dfun
+i₂ = +₁∘i₂
τ : Q₂ ⇒ Q₂
τ = IsPullback.universal Q₂-pb D!w₂≈∞!
w₂≈q₂τ : w₂ ≈ q₂ ∘ τ
w₂≈q₂τ = sym (IsPullback.p₁∘universal≈h₁ Q₂-pb {eq = D!w₂≈∞!})
out∘q₂≈i₂q₂τ : out ∘ q₂ ≈ (id +₁ q₂) ∘ (i₂ ∘ τ)
out∘q₂≈i₂q₂τ = begin
out ∘ q₂ ≈⟨ out∘q₂≈i₂w₂ ⟩
i₂ ∘ w₂ ≈⟨ refl⟩∘⟨ w₂≈q₂τ ⟩
i₂ ∘ q₂ ∘ τ ≈⟨ extendʳ (sym inject₂) ⟩
(id +₁ q₂) ∘ i₂ ∘ τ ∎
q₂≈∞! : q₂ ≈ ∞ {X} ∘ !
q₂≈∞! = sym (coit-unique (i₂ ∘ τ) q₂ out∘q₂≈i₂q₂τ) ○ coit-unique (i₂ ∘ τ) (∞ ∘ !) eq∞
where
eq∞ : out ∘ (∞ ∘ !) ≈ (id +₁ (∞ ∘ !)) ∘ (i₂ ∘ τ)
eq∞ = begin
out ∘ ∞ ∘ ! ≈⟨ extendʳ (∞-commutes ○ inject₂) ⟩
i₂ ∘ ∞ ∘ ! ≈⟨ refl⟩∘⟨ refl⟩∘⟨ !-unique₂ ⟩
i₂ ∘ ∞ ∘ ! ∘ τ ≈⟨ refl⟩∘⟨ sym-assoc ⟩
i₂ ∘ (∞ ∘ !) ∘ τ ≈⟨ extendʳ inject₂ ⟨
(id +₁ (∞ ∘ !)) ∘ i₂ ∘ τ ∎
Q₂-subterminal : ∀ {A} (g h : A ⇒ Q₂) → g ≈ h
Q₂-subterminal g h = q₂-mono g h (begin
q₂ ∘ g ≈⟨ pushˡ q₂≈∞! ⟩
∞ ∘ ! ∘ g ≈⟨ refl⟩∘⟨ !-unique₂ ⟩
∞ ∘ ! ∘ h ≈⟨ pushˡ q₂≈∞! ⟨
q₂ ∘ h ∎)
point₂ : ⊤ ⇒ Q₂
point₂ = IsPullback.universal Q₂-pb (∞-natural ! ○ sym identityʳ)
Q₂≅⊤ : Q₂ ≅ ⊤
Q₂≅⊤ = record
{ from = !
; to = point₂
; iso = record { isoˡ = Q₂-subterminal (point₂ ∘ !) id ; isoʳ = !-unique₂ }
}
α₂-iso : IsIso point₂
α₂-iso = record { inv = ! ; iso = Iso-swap (_≅_.iso Q₂≅⊤) }
IsCop-ι∞ : IsCoproduct ι (∞ {X})
IsCop-ι∞ = IsCoproduct-resp-≈ (IsPullback.p₁∘universal≈h₁ Q₁-pb)
(IsPullback.p₁∘universal≈h₁ Q₂-pb {eq = ∞-natural ! ○ sym identityʳ})
(IsCoproduct-precompose-iso _ _ DX-coproduct α₁-iso α₂-iso)