{-# OPTIONS --safe #-}
module Data.Pushout where
open import Level
open import HLevels
open import Path
open import Function
open import Data.Sigma
open import Path.Reasoning
data SetPushout {A : Type a} {B : Type b} {C : Type c}
(f : A → B) (g : A → C) : Type (a ℓ⊔ b ℓ⊔ c) where
inl : B → SetPushout f g
inr : C → SetPushout f g
push : (a : A) → inl (f a) ≡ inr (g a)
trunc : isSet (SetPushout f g)
module _
{f : A → B} {g : A → C}
(P : SetPushout f g → Type p)
(prop : (x : SetPushout f g) → isProp (P x))
(PB : (b : B) → P (inl b))
(PC : (c : C) → P (inr c)) where
elimProp : (x : SetPushout f g) → P x
elimProp (inl x) = PB x
elimProp (inr x) = PC x
elimProp (push a i) = isOfHLevel→isOfHLevelDep 1 prop (PB (f a)) (PC (g a)) (push a) i
elimProp (trunc xs ys p q i j) =
isOfHLevel→isOfHLevelDep 2
(λ x → isProp→isSet (prop x))
(elimProp xs) (elimProp ys)
(cong elimProp p) (cong elimProp q)
(trunc xs ys p q)
i j
module _ {ℓ} {X : Type ℓ} {f : A → B} {g : A → C}
(set : isSet X)
(h₁ : B → X) (h₂ : C → X)
(cancel : h₁ ∘ f ≡ h₂ ∘ g)
where
rec : SetPushout f g → X
rec (inl x) = h₁ x
rec (inr x) = h₂ x
rec (push a i) = cancel i a
rec (trunc xs ys p q i j) =
set (rec xs) (rec ys) (cong rec p) (cong rec q) i j
ump : Σ![ u ⦂ (SetPushout f g → X) ] × (u ∘ inl ≡ h₁) × (u ∘ inr ≡ h₂)
ump .fst = rec
ump .snd .fst .fst = refl
ump .snd .fst .snd = refl
ump .snd .snd y (l , r) =
funExt (elimProp
_
(λ _ → set _ _)
(λ a → cong (_$ a) (sym l))
(λ c → cong (_$ c) (sym r)))