l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem inr_pushoutZeroZeroIso_hom (X Y : C) [HasBinaryCoproduct X Y] :
    pushout.inr ≫ (pushoutZeroZeroIso X Y).hom = coprod.inr := by
  

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
X Y : C
inst✝ : HasBinaryCoproduct X Y
⊢ pushout.inr ≫ (pushoutZeroZeroIso X Y).hom = coprod.inr

Next tactic:
dsimp [pushoutZeroZeroIso]
@[simp]
theorem inr_pushoutZeroZeroIso_hom (X Y : C) [HasBinaryCoproduct X Y] :
    pushout.inr ≫ (pushoutZeroZeroIso X Y).hom = coprod.inr := by
  dsimp [pushoutZeroZeroIso]
  

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
X Y : C
inst✝ : HasBinaryCoproduct X Y
⊢ pushout.inr ≫
      (colimit.isoColimitCocone
          { cocone := PushoutCocone.mk coprod.inl coprod.inr (_ : 0 ≫ coprod.inl = 0 ≫ coprod.inr),
            isColimit :=
              isPushoutOfIsInitialIsCoproduct coprod.inl coprod.inr 0 0 HasZeroObject.zeroIsInitial
                (coprodIsCoprod X Y) }).hom =
    coprod.inr

Next tactic:
simp
@[simp]
theorem inl_pushoutZeroZeroIso_inv (X Y : C) [HasBinaryCoproduct X Y] :
    coprod.inl ≫ (pushoutZeroZeroIso X Y).inv = pushout.inl := by 

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
X Y : C
inst✝ : HasBinaryCoproduct X Y
⊢ coprod.inl ≫ (pushoutZeroZeroIso X Y).inv = pushout.inl

Next tactic:
simp [Iso.comp_inv_eq]
@[simp]
theorem inr_pushoutZeroZeroIso_inv (X Y : C) [HasBinaryCoproduct X Y] :
    coprod.inr ≫ (pushoutZeroZeroIso X Y).inv = pushout.inr := by 

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
X Y : C
inst✝ : HasBinaryCoproduct X Y
⊢ coprod.inr ≫ (pushoutZeroZeroIso X Y).inv = pushout.inr

Next tactic:
simp [Iso.comp_inv_eq]
lemma partialSups_iff_forall {f : ℕ → α} (p : α → Prop)
    (hp : ∀ {a b}, p (a ⊔ b) ↔ p a ∧ p b) : ∀  {n : ℕ}, p (partialSups f n) ↔ ∀ k ≤ n, p (f k)
  | 0 => by 

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
p : α → Prop
hp : ∀ {a b : α}, p (a ⊔ b) ↔ p a ∧ p b
⊢ p ((partialSups f) 0) ↔ ∀ k ≤ 0, p (f k)

Next tactic:
simp
lemma partialSups_iff_forall {f : ℕ → α} (p : α → Prop)
    (hp : ∀ {a b}, p (a ⊔ b) ↔ p a ∧ p b) : ∀  {n : ℕ}, p (partialSups f n) ↔ ∀ k ≤ n, p (f k)
  | 0 => by simp
  | (n + 1) => by 

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
p : α → Prop
hp : ∀ {a b : α}, p (a ⊔ b) ↔ p a ∧ p b
n : ℕ
⊢ p ((partialSups f) (n + 1)) ↔ ∀ k ≤ n + 1, p (f k)

Next tactic:
simp [hp, partialSups_iff_forall, ← Nat.lt_succ_iff, ← Nat.forall_lt_succ]
@[simp]
lemma upperBounds_range_partialSups (f : ℕ → α) :
    upperBounds (Set.range (partialSups f)) = upperBounds (Set.range f) := by
  

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
⊢ upperBounds (Set.range ⇑(partialSups f)) = upperBounds (Set.range f)

Next tactic:
ext a
@[simp]
lemma upperBounds_range_partialSups (f : ℕ → α) :
    upperBounds (Set.range (partialSups f)) = upperBounds (Set.range f) := by
  ext a
  

Proof state:
case h
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
a : α
⊢ a ∈ upperBounds (Set.range ⇑(partialSups f)) ↔ a ∈ upperBounds (Set.range f)

Next tactic:
simp only [mem_upperBounds, Set.forall_range_iff, partialSups_le_iff]
@[simp]
lemma upperBounds_range_partialSups (f : ℕ → α) :
    upperBounds (Set.range (partialSups f)) = upperBounds (Set.range f) := by
  ext a
  simp only [mem_upperBounds, Set.forall_range_iff, partialSups_le_iff]
  

Proof state:
case h
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
a : α
⊢ (∀ (i k : ℕ), k ≤ i → f k ≤ a) ↔ ∀ (i : ℕ), f i ≤ a

Next tactic:
exact ⟨fun h _ ↦ h _ _ le_rfl, fun h _ _ _ ↦ h _⟩
theorem Monotone.partialSups_eq {f : ℕ → α} (hf : Monotone f) : (partialSups f : ℕ → α) = f := by
  

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
hf : Monotone f
⊢ ⇑(partialSups f) = f

Next tactic:
ext n
theorem Monotone.partialSups_eq {f : ℕ → α} (hf : Monotone f) : (partialSups f : ℕ → α) = f := by
  ext n
  

Proof state:
case h
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
hf : Monotone f
n : ℕ
⊢ (partialSups f) n = f n

Next tactic:
induction' n with n ih
theorem Monotone.partialSups_eq {f : ℕ → α} (hf : Monotone f) : (partialSups f : ℕ → α) = f := by
  ext n
  induction' n with n ih
  · 

Proof state:
case h.zero
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
hf : Monotone f
⊢ (partialSups f) Nat.zero = f Nat.zero

Next tactic:
rfl
theorem Monotone.partialSups_eq {f : ℕ → α} (hf : Monotone f) : (partialSups f : ℕ → α) = f := by
  ext n
  induction' n with n ih
  · rfl
  · 

Proof state:
case h.succ
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
hf : Monotone f
n : ℕ
ih : (partialSups f) n = f n
⊢ (partialSups f) (Nat.succ n) = f (Nat.succ n)

Next tactic:
rw [partialSups_succ, ih, sup_eq_right.2 (hf (Nat.le_succ _))]
/-- `partialSups` forms a Galois insertion with the coercion from monotone functions to functions.
-/
def partialSups.gi : GaloisInsertion (partialSups : (ℕ → α) → ℕ →o α) (↑) where
  choice f h :=
    ⟨f, by 

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
h : ⇑(partialSups f) ≤ f
⊢ Monotone f

Next tactic:
convert (partialSups f).monotone using 1
/-- `partialSups` forms a Galois insertion with the coercion from monotone functions to functions.
-/
def partialSups.gi : GaloisInsertion (partialSups : (ℕ → α) → ℕ →o α) (↑) where
  choice f h :=
    ⟨f, by convert (partialSups f).monotone using 1; 

Proof state:
case h.e'_5
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
h : ⇑(partialSups f) ≤ f
⊢ f = ⇑(partialSups f)

Next tactic:
exact (le_partialSups f).antisymm h
/-- `partialSups` forms a Galois insertion with the coercion from monotone functions to functions.
-/
def partialSups.gi : GaloisInsertion (partialSups : (ℕ → α) → ℕ →o α) (↑) where
  choice f h :=
    ⟨f, by convert (partialSups f).monotone using 1; exact (le_partialSups f).antisymm h⟩
  gc f g := by
    

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
g : ℕ →o α
⊢ partialSups f ≤ g ↔ f ≤ ⇑g

Next tactic:
refine' ⟨(le_partialSups f).trans, fun h => _⟩
/-- `partialSups` forms a Galois insertion with the coercion from monotone functions to functions.
-/
def partialSups.gi : GaloisInsertion (partialSups : (ℕ → α) → ℕ →o α) (↑) where
  choice f h :=
    ⟨f, by convert (partialSups f).monotone using 1; exact (le_partialSups f).antisymm h⟩
  gc f g := by
    refine' ⟨(le_partialSups f).trans, fun h => _⟩
    

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
g : ℕ →o α
h : f ≤ ⇑g
⊢ partialSups f ≤ g

Next tactic:
convert partialSups_mono h
/-- `partialSups` forms a Galois insertion with the coercion from monotone functions to functions.
-/
def partialSups.gi : GaloisInsertion (partialSups : (ℕ → α) → ℕ →o α) (↑) where
  choice f h :=
    ⟨f, by convert (partialSups f).monotone using 1; exact (le_partialSups f).antisymm h⟩
  gc f g := by
    refine' ⟨(le_partialSups f).trans, fun h => _⟩
    convert partialSups_mono h
    

Proof state:
case h.e'_4
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
g : ℕ →o α
h : f ≤ ⇑g
⊢ g = partialSups ⇑g

Next tactic:
exact OrderHom.ext _ _ g.monotone.partialSups_eq.symm
theorem partialSups_eq_sup'_range (f : ℕ → α) (n : ℕ) :
    partialSups f n = (Finset.range (n + 1)).sup' ⟨n, Finset.self_mem_range_succ n⟩ f :=
  eq_of_forall_ge_iff fun _ ↦ by 

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
f : ℕ → α
n : ℕ
x✝ : α
⊢ (partialSups f) n ≤ x✝ ↔ Finset.sup' (Finset.range (n + 1)) (_ : ∃ x, x ∈ Finset.range (n + 1)) f ≤ x✝

Next tactic:
simp [Nat.lt_succ_iff]
lemma partialSups_apply {ι : Type*} {π : ι → Type*} [(i : ι) → SemilatticeSup (π i)]
    (f : ℕ → (i : ι) → π i) (n : ℕ) (i : ι) : partialSups f n i = partialSups (f · i) n := by
  

Proof state:
α : Type u_1
inst✝¹ : SemilatticeSup α
ι : Type u_2
π : ι → Type u_3
inst✝ : (i : ι) → SemilatticeSup (π i)
f : ℕ → (i : ι) → π i
n : ℕ
i : ι
⊢ (partialSups f) n i = (partialSups fun x => f x i) n

Next tactic:
simp only [partialSups_eq_sup'_range, Finset.sup'_apply]
theorem partialSups_eq_sup_range [SemilatticeSup α] [OrderBot α] (f : ℕ → α) (n : ℕ) :
    partialSups f n = (Finset.range (n + 1)).sup f :=
  eq_of_forall_ge_iff fun _ ↦ by 

Proof state:
α : Type u_1
inst✝¹ : SemilatticeSup α
inst✝ : OrderBot α
f : ℕ → α
n : ℕ
x✝ : α
⊢ (partialSups f) n ≤ x✝ ↔ Finset.sup (Finset.range (n + 1)) f ≤ x✝

Next tactic:
simp [Nat.lt_succ_iff]
theorem partialSups_eq_ciSup_Iic (f : ℕ → α) (n : ℕ) : partialSups f n = ⨆ i : Set.Iic n, f i :=
  eq_of_forall_ge_iff fun _ ↦ by
    

Proof state:
α : Type u_1
inst✝ : ConditionallyCompleteLattice α
f : ℕ → α
n : ℕ
x✝ : α
⊢ (partialSups f) n ≤ x✝ ↔ ⨆ i, f ↑i ≤ x✝

Next tactic:
rw [ciSup_set_le_iff Set.nonempty_Iic ((Set.finite_le_nat _).image _).bddAbove,
      partialSups_le_iff]
theorem partialSups_eq_ciSup_Iic (f : ℕ → α) (n : ℕ) : partialSups f n = ⨆ i : Set.Iic n, f i :=
  eq_of_forall_ge_iff fun _ ↦ by
    rw [ciSup_set_le_iff Set.nonempty_Iic ((Set.finite_le_nat _).image _).bddAbove,
      partialSups_le_iff]; 

Proof state:
α : Type u_1
inst✝ : ConditionallyCompleteLattice α
f : ℕ → α
n : ℕ
x✝ : α
⊢ (∀ k ≤ n, f k ≤ x✝) ↔ ∀ i ∈ Set.Iic n, f i ≤ x✝

Next tactic:
rfl
@[simp]
theorem ciSup_partialSups_eq {f : ℕ → α} (h : BddAbove (Set.range f)) :
    ⨆ n, partialSups f n = ⨆ n, f n := by
  

Proof state:
α : Type u_1
inst✝ : ConditionallyCompleteLattice α
f : ℕ → α
h : BddAbove (Set.range f)
⊢ ⨆ n, (partialSups f) n = ⨆ n, f n

Next tactic:
refine' (ciSup_le fun n => _).antisymm (ciSup_mono _ <| le_partialSups f)
@[simp]
theorem ciSup_partialSups_eq {f : ℕ → α} (h : BddAbove (Set.range f)) :
    ⨆ n, partialSups f n = ⨆ n, f n := by
  refine' (ciSup_le fun n => _).antisymm (ciSup_mono _ <| le_partialSups f)
  · 

Proof state:
case refine'_1
α : Type u_1
inst✝ : ConditionallyCompleteLattice α
f : ℕ → α
h : BddAbove (Set.range f)
n : ℕ
⊢ (partialSups f) n ≤ ⨆ n, f n

Next tactic:
rw [partialSups_eq_ciSup_Iic]
@[simp]
theorem ciSup_partialSups_eq {f : ℕ → α} (h : BddAbove (Set.range f)) :
    ⨆ n, partialSups f n = ⨆ n, f n := by
  refine' (ciSup_le fun n => _).antisymm (ciSup_mono _ <| le_partialSups f)
  · rw [partialSups_eq_ciSup_Iic]
    

Proof state:
case refine'_1
α : Type u_1
inst✝ : ConditionallyCompleteLattice α
f : ℕ → α
h : BddAbove (Set.range f)
n : ℕ
⊢ ⨆ i, f ↑i ≤ ⨆ n, f n

Next tactic:
exact ciSup_le fun i => le_ciSup h _
@[simp]
theorem ciSup_partialSups_eq {f : ℕ → α} (h : BddAbove (Set.range f)) :
    ⨆ n, partialSups f n = ⨆ n, f n := by
  refine' (ciSup_le fun n => _).antisymm (ciSup_mono _ <| le_partialSups f)
  · rw [partialSups_eq_ciSup_Iic]
    exact ciSup_le fun i => le_ciSup h _
  · 

Proof state:
case refine'_2
α : Type u_1
inst✝ : ConditionallyCompleteLattice α
f : ℕ → α
h : BddAbove (Set.range f)
⊢ BddAbove (Set.range fun n => (partialSups f) n)

Next tactic:
rwa [bddAbove_range_partialSups]
theorem partialSups_eq_biSup (f : ℕ → α) (n : ℕ) : partialSups f n = ⨆ i ≤ n, f i := by
  

Proof state:
α : Type u_1
inst✝ : CompleteLattice α
f : ℕ → α
n : ℕ
⊢ (partialSups f) n = ⨆ i, ⨆ (_ : i ≤ n), f i

Next tactic:
simpa only [iSup_subtype] using partialSups_eq_ciSup_Iic f n
theorem iSup_le_iSup_of_partialSups_le_partialSups {f g : ℕ → α}
    (h : partialSups f ≤ partialSups g) : ⨆ n, f n ≤ ⨆ n, g n := by
  

Proof state:
α : Type u_1
inst✝ : CompleteLattice α
f g : ℕ → α
h : partialSups f ≤ partialSups g
⊢ ⨆ n, f n ≤ ⨆ n, g n

Next tactic:
rw [← iSup_partialSups_eq f, ← iSup_partialSups_eq g]
theorem iSup_le_iSup_of_partialSups_le_partialSups {f g : ℕ → α}
    (h : partialSups f ≤ partialSups g) : ⨆ n, f n ≤ ⨆ n, g n := by
  rw [← iSup_partialSups_eq f, ← iSup_partialSups_eq g]
  

Proof state:
α : Type u_1
inst✝ : CompleteLattice α
f g : ℕ → α
h : partialSups f ≤ partialSups g
⊢ ⨆ n, (partialSups f) n ≤ ⨆ n, (partialSups g) n

Next tactic:
exact iSup_mono h
theorem iSup_eq_iSup_of_partialSups_eq_partialSups {f g : ℕ → α}
    (h : partialSups f = partialSups g) : ⨆ n, f n = ⨆ n, g n := by
  

Proof state:
α : Type u_1
inst✝ : CompleteLattice α
f g : ℕ → α
h : partialSups f = partialSups g
⊢ ⨆ n, f n = ⨆ n, g n

Next tactic:
simp_rw [← iSup_partialSups_eq f, ← iSup_partialSups_eq g, h]
/-- Composition of morphisms of `Bipointed`. -/
@[simps]
def comp {X Y Z : Bipointed.{u}} (f : Bipointed.Hom X Y) (g : Bipointed.Hom Y Z) :
    Bipointed.Hom X Z :=
  ⟨g.toFun ∘ f.toFun, by 

Proof state:
α : Type u_1
β : Type u_2
X Y Z : Bipointed
f : Bipointed.Hom X Y
g : Bipointed.Hom Y Z
⊢ (g.toFun ∘ f.toFun) X.toProd.1 = Z.toProd.1

Next tactic:
rw [Function.comp_apply, f.map_fst, g.map_fst]
/-- Composition of morphisms of `Bipointed`. -/
@[simps]
def comp {X Y Z : Bipointed.{u}} (f : Bipointed.Hom X Y) (g : Bipointed.Hom Y Z) :
    Bipointed.Hom X Z :=
  ⟨g.toFun ∘ f.toFun, by rw [Function.comp_apply, f.map_fst, g.map_fst], by
    

Proof state:
α : Type u_1
β : Type u_2
X Y Z : Bipointed
f : Bipointed.Hom X Y
g : Bipointed.Hom Y Z
⊢ (g.toFun ∘ f.toFun) X.toProd.2 = Z.toProd.2

Next tactic:
rw [Function.comp_apply, f.map_snd, g.map_snd]
/-- The free/forgetful adjunction between `PointedToBipointed_fst` and `BipointedToPointed_fst`.
-/
def pointedToBipointedFstBipointedToPointedFstAdjunction :
    pointedToBipointedFst ⊣ bipointedToPointedFst :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_fst⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.2 f.toFun, f.map_point, rfl⟩
          left_inv := fun f => by
            

Proof state:
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedFst.obj X ⟶ Y
⊢ (fun f =>
        { toFun := fun o => Option.elim o Y.toProd.2 f.toFun,
          map_fst := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedFst.obj Y).point),
          map_snd :=
            (_ :
              (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2 =
                (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2) })
      ((fun f =>
          { toFun := f.toFun ∘ some,
            map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedFst.obj X).toProd.1 = Y.toProd.1) })
        f) =
    f

Next tactic:
apply Bipointed.Hom.ext
/-- The free/forgetful adjunction between `PointedToBipointed_fst` and `BipointedToPointed_fst`.
-/
def pointedToBipointedFstBipointedToPointedFstAdjunction :
    pointedToBipointedFst ⊣ bipointedToPointedFst :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_fst⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.2 f.toFun, f.map_point, rfl⟩
          left_inv := fun f => by
            apply Bipointed.Hom.ext
            

Proof state:
case toFun
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedFst.obj X ⟶ Y
⊢ ((fun f =>
          { toFun := fun o => Option.elim o Y.toProd.2 f.toFun,
            map_fst := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedFst.obj Y).point),
            map_snd :=
              (_ :
                (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2 =
                  (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2) })
        ((fun f =>
            { toFun := f.toFun ∘ some,
              map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedFst.obj X).toProd.1 = Y.toProd.1) })
          f)).toFun =
    f.toFun

Next tactic:
funext x
/-- The free/forgetful adjunction between `PointedToBipointed_fst` and `BipointedToPointed_fst`.
-/
def pointedToBipointedFstBipointedToPointedFstAdjunction :
    pointedToBipointedFst ⊣ bipointedToPointedFst :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_fst⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.2 f.toFun, f.map_point, rfl⟩
          left_inv := fun f => by
            apply Bipointed.Hom.ext
            funext x
            

Proof state:
case toFun.h
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedFst.obj X ⟶ Y
x : (pointedToBipointedFst.obj X).X
⊢ Bipointed.Hom.toFun
      ((fun f =>
          { toFun := fun o => Option.elim o Y.toProd.2 f.toFun,
            map_fst := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedFst.obj Y).point),
            map_snd :=
              (_ :
                (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2 =
                  (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2) })
        ((fun f =>
            { toFun := f.toFun ∘ some,
              map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedFst.obj X).toProd.1 = Y.toProd.1) })
          f))
      x =
    Bipointed.Hom.toFun f x

Next tactic:
cases x
/-- The free/forgetful adjunction between `PointedToBipointed_fst` and `BipointedToPointed_fst`.
-/
def pointedToBipointedFstBipointedToPointedFstAdjunction :
    pointedToBipointedFst ⊣ bipointedToPointedFst :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_fst⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.2 f.toFun, f.map_point, rfl⟩
          left_inv := fun f => by
            apply Bipointed.Hom.ext
            funext x
            cases x
            · 

Proof state:
case toFun.h.none
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedFst.obj X ⟶ Y
⊢ Bipointed.Hom.toFun
      ((fun f =>
          { toFun := fun o => Option.elim o Y.toProd.2 f.toFun,
            map_fst := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedFst.obj Y).point),
            map_snd :=
              (_ :
                (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2 =
                  (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2) })
        ((fun f =>
            { toFun := f.toFun ∘ some,
              map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedFst.obj X).toProd.1 = Y.toProd.1) })
          f))
      none =
    Bipointed.Hom.toFun f none

Next tactic:
exact f.map_snd.symm
/-- The free/forgetful adjunction between `PointedToBipointed_fst` and `BipointedToPointed_fst`.
-/
def pointedToBipointedFstBipointedToPointedFstAdjunction :
    pointedToBipointedFst ⊣ bipointedToPointedFst :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_fst⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.2 f.toFun, f.map_point, rfl⟩
          left_inv := fun f => by
            apply Bipointed.Hom.ext
            funext x
            cases x
            · exact f.map_snd.symm
            · 

Proof state:
case toFun.h.some
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedFst.obj X ⟶ Y
val✝ : X.X
⊢ Bipointed.Hom.toFun
      ((fun f =>
          { toFun := fun o => Option.elim o Y.toProd.2 f.toFun,
            map_fst := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedFst.obj Y).point),
            map_snd :=
              (_ :
                (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2 =
                  (fun o => Option.elim o Y.toProd.2 f.toFun) (pointedToBipointedFst.obj X).toProd.2) })
        ((fun f =>
            { toFun := f.toFun ∘ some,
              map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedFst.obj X).toProd.1 = Y.toProd.1) })
          f))
      (some val✝) =
    Bipointed.Hom.toFun f (some val✝)

Next tactic:
rfl
/-- The free/forgetful adjunction between `PointedToBipointed_snd` and `BipointedToPointed_snd`.
-/
def pointedToBipointedSndBipointedToPointedSndAdjunction :
    pointedToBipointedSnd ⊣ bipointedToPointedSnd :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_snd⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.1 f.toFun, rfl, f.map_point⟩
          left_inv := fun f => by
            

Proof state:
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedSnd.obj X ⟶ Y
⊢ (fun f =>
        { toFun := fun o => Option.elim o Y.toProd.1 f.toFun,
          map_fst :=
            (_ :
              (fun o => Option.elim o Y.toProd.1 f.toFun) (pointedToBipointedSnd.obj X).toProd.1 =
                (fun o => Option.elim o Y.toProd.1 f.toFun) (pointedToBipointedSnd.obj X).toProd.1),
          map_snd := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedSnd.obj Y).point) })
      ((fun f =>
          { toFun := f.toFun ∘ some,
            map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedSnd.obj X).toProd.2 = Y.toProd.2) })
        f) =
    f

Next tactic:
apply Bipointed.Hom.ext
/-- The free/forgetful adjunction between `PointedToBipointed_snd` and `BipointedToPointed_snd`.
-/
def pointedToBipointedSndBipointedToPointedSndAdjunction :
    pointedToBipointedSnd ⊣ bipointedToPointedSnd :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_snd⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.1 f.toFun, rfl, f.map_point⟩
          left_inv := fun f => by
            apply Bipointed.Hom.ext
            

Proof state:
case toFun
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedSnd.obj X ⟶ Y
⊢ ((fun f =>
          { toFun := fun o => Option.elim o Y.toProd.1 f.toFun,
            map_fst :=
              (_ :
                (fun o => Option.elim o Y.toProd.1 f.toFun) (pointedToBipointedSnd.obj X).toProd.1 =
                  (fun o => Option.elim o Y.toProd.1 f.toFun) (pointedToBipointedSnd.obj X).toProd.1),
            map_snd := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedSnd.obj Y).point) })
        ((fun f =>
            { toFun := f.toFun ∘ some,
              map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedSnd.obj X).toProd.2 = Y.toProd.2) })
          f)).toFun =
    f.toFun

Next tactic:
funext x
/-- The free/forgetful adjunction between `PointedToBipointed_snd` and `BipointedToPointed_snd`.
-/
def pointedToBipointedSndBipointedToPointedSndAdjunction :
    pointedToBipointedSnd ⊣ bipointedToPointedSnd :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => ⟨f.toFun ∘ Option.some, f.map_snd⟩
          invFun := fun f => ⟨fun o => o.elim Y.toProd.1 f.toFun, rfl, f.map_point⟩
          left_inv := fun f => by
            apply Bipointed.Hom.ext
            funext x
            

Proof state:
case toFun.h
α : Type u_1
β : Type u_2
X : Pointed
Y : Bipointed
f : pointedToBipointedSnd.obj X ⟶ Y
x : (pointedToBipointedSnd.obj X).X
⊢ Bipointed.Hom.toFun
      ((fun f =>
          { toFun := fun o => Option.elim o Y.toProd.1 f.toFun,
            map_fst :=
              (_ :
                (fun o => Option.elim o Y.toProd.1 f.toFun) (pointedToBipointedSnd.obj X).toProd.1 =
                  (fun o => Option.elim o Y.toProd.1 f.toFun) (pointedToBipointedSnd.obj X).toProd.1),
            map_snd := (_ : Pointed.Hom.toFun f X.point = (bipointedToPointedSnd.obj Y).point) })
        ((fun f =>
            { toFun := f.toFun ∘ some,
              map_point := (_ : Bipointed.Hom.toFun f (pointedToBipointedSnd.obj X).toProd.2 = Y.toProd.2) })
          f))
      x =
    Bipointed.Hom.toFun f x

Next tactic:
cases x