{-# 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)))