l3lab/ntp-mathlib huggingface dataset:
/-- An equivalence from `WalkingPair` to `Bool`, sometimes useful when reindexing limits.
-/
def WalkingPair.equivBool : WalkingPair ≃ Bool
    where
  toFun j := WalkingPair.recOn j true false
  -- to match equiv.sum_equiv_sigma_bool
  invFun b := Bool.recOn b right left
  left_inv j := by cases j; repeat rfl
  right_inv b := by cases b; repeat 

Proof state:
case false
⊢ (fun j => WalkingPair.recOn j true false) ((fun b => Bool.recOn b right left) false) = false
case true ⊢ (fun j => WalkingPair.recOn j true false) ((fun b => Bool.recOn b right left) true) = true

Next tactic:
rfl
/-- An equivalence from `WalkingPair` to `Bool`, sometimes useful when reindexing limits.
-/
def WalkingPair.equivBool : WalkingPair ≃ Bool
    where
  toFun j := WalkingPair.recOn j true false
  -- to match equiv.sum_equiv_sigma_bool
  invFun b := Bool.recOn b right left
  left_inv j := by cases j; repeat rfl
  right_inv b := by cases b; repeat 

Proof state:
case true
⊢ (fun j => WalkingPair.recOn j true false) ((fun b => Bool.recOn b right left) true) = true

Next tactic:
rfl
/-- An equivalence from `WalkingPair` to `Bool`, sometimes useful when reindexing limits.
-/
def WalkingPair.equivBool : WalkingPair ≃ Bool
    where
  toFun j := WalkingPair.recOn j true false
  -- to match equiv.sum_equiv_sigma_bool
  invFun b := Bool.recOn b right left
  left_inv j := by cases j; repeat rfl
  right_inv b := by cases b; repeat 

Proof state:

Next tactic:
rfl
/-- The natural transformation between two functors out of the
 walking pair, specified by its components. -/
def mapPair : F ⟶ G where
  app j := Discrete.recOn j fun j => WalkingPair.casesOn j f g
  naturality := fun ⟨X⟩ ⟨Y⟩ ⟨⟨u⟩⟩ => by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F G : Discrete WalkingPair ⥤ C
f : F.obj { as := left } ⟶ G.obj { as := left }
g : F.obj { as := right } ⟶ G.obj { as := right }
x✝² x✝¹ : Discrete WalkingPair
X Y : WalkingPair
x✝ : { as := X } ⟶ { as := Y }
u : { as := X }.as = { as := Y }.as
⊢ F.map { down := { down := u } } ≫ (fun j => Discrete.recOn j fun j => WalkingPair.casesOn j f g) { as := Y } =
    (fun j => Discrete.recOn j fun j => WalkingPair.casesOn j f g) { as := X } ≫ G.map { down := { down := u } }

Next tactic:
aesop_cat
/-- The natural isomorphism between two functors out of the walking pair, specified by its
components. -/
@[simps!]
def mapPairIso (f : F.obj ⟨left⟩ ≅ G.obj ⟨left⟩) (g : F.obj ⟨right⟩ ≅ G.obj ⟨right⟩) : F ≅ G :=
  NatIso.ofComponents (fun j => Discrete.recOn j fun j => WalkingPair.casesOn j f g)
    (fun ⟨⟨u⟩⟩ => by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F G : Discrete WalkingPair ⥤ C
f✝ : F.obj { as := left } ⟶ G.obj { as := left }
g✝ : F.obj { as := right } ⟶ G.obj { as := right }
f : F.obj { as := left } ≅ G.obj { as := left }
g : F.obj { as := right } ≅ G.obj { as := right }
X✝ Y✝ : Discrete WalkingPair
x✝ : X✝ ⟶ Y✝
u : X✝.as = Y✝.as
⊢ F.map { down := { down := u } } ≫ ((fun j => Discrete.recOn j fun j => WalkingPair.casesOn j f g) Y✝).hom =
    ((fun j => Discrete.recOn j fun j => WalkingPair.casesOn j f g) X✝).hom ≫ G.map { down := { down := u } }

Next tactic:
aesop_cat
/-- A convenient way to show that a binary fan is a limit. -/
def BinaryFan.IsLimit.mk {X Y : C} (s : BinaryFan X Y)
    (lift : ∀ {T : C} (_ : T ⟶ X) (_ : T ⟶ Y), T ⟶ s.pt)
    (hl₁ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ s.fst = f)
    (hl₂ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ s.snd = g)
    (uniq :
      ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y) (m : T ⟶ s.pt) (_ : m ≫ s.fst = f) (_ : m ≫ s.snd = g),
        m = lift f g) :
    IsLimit s :=
  Limits.IsLimit.mk (fun t => lift (BinaryFan.fst t) (BinaryFan.snd t))
    (by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
s : BinaryFan X Y
lift : {T : C} → (T ⟶ X) → (T ⟶ Y) → (T ⟶ s.pt)
hl₁ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ fst s = f
hl₂ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ snd s = g
uniq : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y) (m : T ⟶ s.pt), m ≫ fst s = f → m ≫ snd s = g → m = lift f g
⊢ ∀ (s_1 : Cone (pair X Y)) (j : Discrete WalkingPair), (fun t => lift (fst t) (snd t)) s_1 ≫ s.π.app j = s_1.π.app j

Next tactic:
rintro t (rfl | rfl)
/-- A convenient way to show that a binary fan is a limit. -/
def BinaryFan.IsLimit.mk {X Y : C} (s : BinaryFan X Y)
    (lift : ∀ {T : C} (_ : T ⟶ X) (_ : T ⟶ Y), T ⟶ s.pt)
    (hl₁ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ s.fst = f)
    (hl₂ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ s.snd = g)
    (uniq :
      ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y) (m : T ⟶ s.pt) (_ : m ≫ s.fst = f) (_ : m ≫ s.snd = g),
        m = lift f g) :
    IsLimit s :=
  Limits.IsLimit.mk (fun t => lift (BinaryFan.fst t) (BinaryFan.snd t))
    (by
      rintro t (rfl | rfl)
      · 

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X Y : C
s : BinaryFan X Y
lift : {T : C} → (T ⟶ X) → (T ⟶ Y) → (T ⟶ s.pt)
hl₁ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ fst s = f
hl₂ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ snd s = g
uniq : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y) (m : T ⟶ s.pt), m ≫ fst s = f → m ≫ snd s = g → m = lift f g
t : Cone (pair X Y)
⊢ (fun t => lift (fst t) (snd t)) t ≫ s.π.app { as := left } = t.π.app { as := left }

Next tactic:
exact hl₁ _ _
/-- A convenient way to show that a binary fan is a limit. -/
def BinaryFan.IsLimit.mk {X Y : C} (s : BinaryFan X Y)
    (lift : ∀ {T : C} (_ : T ⟶ X) (_ : T ⟶ Y), T ⟶ s.pt)
    (hl₁ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ s.fst = f)
    (hl₂ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ s.snd = g)
    (uniq :
      ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y) (m : T ⟶ s.pt) (_ : m ≫ s.fst = f) (_ : m ≫ s.snd = g),
        m = lift f g) :
    IsLimit s :=
  Limits.IsLimit.mk (fun t => lift (BinaryFan.fst t) (BinaryFan.snd t))
    (by
      rintro t (rfl | rfl)
      · exact hl₁ _ _
      · 

Proof state:
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X Y : C
s : BinaryFan X Y
lift : {T : C} → (T ⟶ X) → (T ⟶ Y) → (T ⟶ s.pt)
hl₁ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ fst s = f
hl₂ : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y), lift f g ≫ snd s = g
uniq : ∀ {T : C} (f : T ⟶ X) (g : T ⟶ Y) (m : T ⟶ s.pt), m ≫ fst s = f → m ≫ snd s = g → m = lift f g
t : Cone (pair X Y)
⊢ (fun t => lift (fst t) (snd t)) t ≫ s.π.app { as := right } = t.π.app { as := right }

Next tactic:
exact hl₂ _ _
/-- A convenient way to show that a binary cofan is a colimit. -/
def BinaryCofan.IsColimit.mk {X Y : C} (s : BinaryCofan X Y)
    (desc : ∀ {T : C} (_ : X ⟶ T) (_ : Y ⟶ T), s.pt ⟶ T)
    (hd₁ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inl ≫ desc f g = f)
    (hd₂ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inr ≫ desc f g = g)
    (uniq :
      ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T) (m : s.pt ⟶ T) (_ : s.inl ≫ m = f) (_ : s.inr ≫ m = g),
        m = desc f g) :
    IsColimit s :=
  Limits.IsColimit.mk (fun t => desc (BinaryCofan.inl t) (BinaryCofan.inr t))
    (by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
s : BinaryCofan X Y
desc : {T : C} → (X ⟶ T) → (Y ⟶ T) → (s.pt ⟶ T)
hd₁ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), inl s ≫ desc f g = f
hd₂ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), inr s ≫ desc f g = g
uniq : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T) (m : s.pt ⟶ T), inl s ≫ m = f → inr s ≫ m = g → m = desc f g
⊢ ∀ (s_1 : Cocone (pair X Y)) (j : Discrete WalkingPair), s.ι.app j ≫ (fun t => desc (inl t) (inr t)) s_1 = s_1.ι.app j

Next tactic:
rintro t (rfl | rfl)
/-- A convenient way to show that a binary cofan is a colimit. -/
def BinaryCofan.IsColimit.mk {X Y : C} (s : BinaryCofan X Y)
    (desc : ∀ {T : C} (_ : X ⟶ T) (_ : Y ⟶ T), s.pt ⟶ T)
    (hd₁ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inl ≫ desc f g = f)
    (hd₂ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inr ≫ desc f g = g)
    (uniq :
      ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T) (m : s.pt ⟶ T) (_ : s.inl ≫ m = f) (_ : s.inr ≫ m = g),
        m = desc f g) :
    IsColimit s :=
  Limits.IsColimit.mk (fun t => desc (BinaryCofan.inl t) (BinaryCofan.inr t))
    (by
      rintro t (rfl | rfl)
      · 

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X Y : C
s : BinaryCofan X Y
desc : {T : C} → (X ⟶ T) → (Y ⟶ T) → (s.pt ⟶ T)
hd₁ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), inl s ≫ desc f g = f
hd₂ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), inr s ≫ desc f g = g
uniq : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T) (m : s.pt ⟶ T), inl s ≫ m = f → inr s ≫ m = g → m = desc f g
t : Cocone (pair X Y)
⊢ s.ι.app { as := left } ≫ (fun t => desc (inl t) (inr t)) t = t.ι.app { as := left }

Next tactic:
exact hd₁ _ _
/-- A convenient way to show that a binary cofan is a colimit. -/
def BinaryCofan.IsColimit.mk {X Y : C} (s : BinaryCofan X Y)
    (desc : ∀ {T : C} (_ : X ⟶ T) (_ : Y ⟶ T), s.pt ⟶ T)
    (hd₁ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inl ≫ desc f g = f)
    (hd₂ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), s.inr ≫ desc f g = g)
    (uniq :
      ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T) (m : s.pt ⟶ T) (_ : s.inl ≫ m = f) (_ : s.inr ≫ m = g),
        m = desc f g) :
    IsColimit s :=
  Limits.IsColimit.mk (fun t => desc (BinaryCofan.inl t) (BinaryCofan.inr t))
    (by
      rintro t (rfl | rfl)
      · exact hd₁ _ _
      · 

Proof state:
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X Y : C
s : BinaryCofan X Y
desc : {T : C} → (X ⟶ T) → (Y ⟶ T) → (s.pt ⟶ T)
hd₁ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), inl s ≫ desc f g = f
hd₂ : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T), inr s ≫ desc f g = g
uniq : ∀ {T : C} (f : X ⟶ T) (g : Y ⟶ T) (m : s.pt ⟶ T), inl s ≫ m = f → inr s ≫ m = g → m = desc f g
t : Cocone (pair X Y)
⊢ s.ι.app { as := right } ≫ (fun t => desc (inl t) (inr t)) t = t.ι.app { as := right }

Next tactic:
exact hd₂ _ _
/-- A binary fan with vertex `P` consists of the two projections `π₁ : P ⟶ X` and `π₂ : P ⟶ Y`. -/
@[simps pt]
def BinaryFan.mk {P : C} (π₁ : P ⟶ X) (π₂ : P ⟶ Y) : BinaryFan X Y where
  pt := P
  π :=
    { app := fun ⟨j⟩ => by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y P : C
π₁ : P ⟶ X
π₂ : P ⟶ Y
x✝ : Discrete WalkingPair
j : WalkingPair
⊢ ((Functor.const (Discrete WalkingPair)).obj P).obj { as := j } ⟶ (pair X Y).obj { as := j }

Next tactic:
cases j
/-- A binary fan with vertex `P` consists of the two projections `π₁ : P ⟶ X` and `π₂ : P ⟶ Y`. -/
@[simps pt]
def BinaryFan.mk {P : C} (π₁ : P ⟶ X) (π₂ : P ⟶ Y) : BinaryFan X Y where
  pt := P
  π :=
    { app := fun ⟨j⟩ => by cases j <;> 

Proof state:
case left
C : Type u
inst✝ : Category.{v, u} C
X Y P : C
π₁ : P ⟶ X
π₂ : P ⟶ Y
x✝ : Discrete WalkingPair
⊢ ((Functor.const (Discrete WalkingPair)).obj P).obj { as := left } ⟶ (pair X Y).obj { as := left }

Next tactic:
simpa
/-- A binary fan with vertex `P` consists of the two projections `π₁ : P ⟶ X` and `π₂ : P ⟶ Y`. -/
@[simps pt]
def BinaryFan.mk {P : C} (π₁ : P ⟶ X) (π₂ : P ⟶ Y) : BinaryFan X Y where
  pt := P
  π :=
    { app := fun ⟨j⟩ => by cases j <;> 

Proof state:
case right
C : Type u
inst✝ : Category.{v, u} C
X Y P : C
π₁ : P ⟶ X
π₂ : P ⟶ Y
x✝ : Discrete WalkingPair
⊢ ((Functor.const (Discrete WalkingPair)).obj P).obj { as := right } ⟶ (pair X Y).obj { as := right }

Next tactic:
simpa
/-- A binary cofan with vertex `P` consists of the two inclusions `ι₁ : X ⟶ P` and `ι₂ : Y ⟶ P`. -/
@[simps pt]
def BinaryCofan.mk {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : BinaryCofan X Y where
  pt := P
  ι :=
    { app := fun ⟨j⟩ => by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y P : C
ι₁ : X ⟶ P
ι₂ : Y ⟶ P
x✝ : Discrete WalkingPair
j : WalkingPair
⊢ (pair X Y).obj { as := j } ⟶ ((Functor.const (Discrete WalkingPair)).obj P).obj { as := j }

Next tactic:
cases j
/-- A binary cofan with vertex `P` consists of the two inclusions `ι₁ : X ⟶ P` and `ι₂ : Y ⟶ P`. -/
@[simps pt]
def BinaryCofan.mk {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : BinaryCofan X Y where
  pt := P
  ι :=
    { app := fun ⟨j⟩ => by cases j <;> 

Proof state:
case left
C : Type u
inst✝ : Category.{v, u} C
X Y P : C
ι₁ : X ⟶ P
ι₂ : Y ⟶ P
x✝ : Discrete WalkingPair
⊢ (pair X Y).obj { as := left } ⟶ ((Functor.const (Discrete WalkingPair)).obj P).obj { as := left }

Next tactic:
simpa
/-- A binary cofan with vertex `P` consists of the two inclusions `ι₁ : X ⟶ P` and `ι₂ : Y ⟶ P`. -/
@[simps pt]
def BinaryCofan.mk {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : BinaryCofan X Y where
  pt := P
  ι :=
    { app := fun ⟨j⟩ => by cases j <;> 

Proof state:
case right
C : Type u
inst✝ : Category.{v, u} C
X Y P : C
ι₁ : X ⟶ P
ι₂ : Y ⟶ P
x✝ : Discrete WalkingPair
⊢ (pair X Y).obj { as := right } ⟶ ((Functor.const (Discrete WalkingPair)).obj P).obj { as := right }

Next tactic:
simpa
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd :=
    Cones.ext (Iso.refl _) fun j => by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryFan X Y
j : Discrete WalkingPair
⊢ c.π.app j = (Iso.refl c.pt).hom ≫ (BinaryFan.mk (BinaryFan.fst c) (BinaryFan.snd c)).π.app j

Next tactic:
cases' j with l
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd :=
    Cones.ext (Iso.refl _) fun j => by cases' j with l; 

Proof state:
case mk
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryFan X Y
l : WalkingPair
⊢ c.π.app { as := l } = (Iso.refl c.pt).hom ≫ (BinaryFan.mk (BinaryFan.fst c) (BinaryFan.snd c)).π.app { as := l }

Next tactic:
cases l
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd :=
    Cones.ext (Iso.refl _) fun j => by cases' j with l; cases l; 

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryFan X Y
⊢ c.π.app { as := left } = (Iso.refl c.pt).hom ≫ (BinaryFan.mk (BinaryFan.fst c) (BinaryFan.snd c)).π.app { as := left }
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryFan X Y
⊢ c.π.app { as := right } =
    (Iso.refl c.pt).hom ≫ (BinaryFan.mk (BinaryFan.fst c) (BinaryFan.snd c)).π.app { as := right }

Next tactic:
repeat simp
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd :=
    Cones.ext (Iso.refl _) fun j => by cases' j with l; cases l; repeat 

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryFan X Y
⊢ c.π.app { as := left } = (Iso.refl c.pt).hom ≫ (BinaryFan.mk (BinaryFan.fst c) (BinaryFan.snd c)).π.app { as := left }
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryFan X Y
⊢ c.π.app { as := right } =
    (Iso.refl c.pt).hom ≫ (BinaryFan.mk (BinaryFan.fst c) (BinaryFan.snd c)).π.app { as := right }

Next tactic:
simp
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd :=
    Cones.ext (Iso.refl _) fun j => by cases' j with l; cases l; repeat 

Proof state:
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryFan X Y
⊢ c.π.app { as := right } =
    (Iso.refl c.pt).hom ≫ (BinaryFan.mk (BinaryFan.fst c) (BinaryFan.snd c)).π.app { as := right }

Next tactic:
simp
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd :=
    Cones.ext (Iso.refl _) fun j => by cases' j with l; cases l; repeat 

Proof state:

Next tactic:
simp
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr :=
    Cocones.ext (Iso.refl _) fun j => by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryCofan X Y
j : Discrete WalkingPair
⊢ c.ι.app j ≫ (Iso.refl c.pt).hom = (BinaryCofan.mk (BinaryCofan.inl c) (BinaryCofan.inr c)).ι.app j

Next tactic:
cases' j with l
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr :=
    Cocones.ext (Iso.refl _) fun j => by cases' j with l; 

Proof state:
case mk
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryCofan X Y
l : WalkingPair
⊢ c.ι.app { as := l } ≫ (Iso.refl c.pt).hom = (BinaryCofan.mk (BinaryCofan.inl c) (BinaryCofan.inr c)).ι.app { as := l }

Next tactic:
cases l
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr :=
    Cocones.ext (Iso.refl _) fun j => by cases' j with l; cases l; 

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryCofan X Y
⊢ c.ι.app { as := left } ≫ (Iso.refl c.pt).hom =
    (BinaryCofan.mk (BinaryCofan.inl c) (BinaryCofan.inr c)).ι.app { as := left }
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryCofan X Y
⊢ c.ι.app { as := right } ≫ (Iso.refl c.pt).hom =
    (BinaryCofan.mk (BinaryCofan.inl c) (BinaryCofan.inr c)).ι.app { as := right }

Next tactic:
repeat simp
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr :=
    Cocones.ext (Iso.refl _) fun j => by cases' j with l; cases l; repeat 

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryCofan X Y
⊢ c.ι.app { as := left } ≫ (Iso.refl c.pt).hom =
    (BinaryCofan.mk (BinaryCofan.inl c) (BinaryCofan.inr c)).ι.app { as := left }
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryCofan X Y
⊢ c.ι.app { as := right } ≫ (Iso.refl c.pt).hom =
    (BinaryCofan.mk (BinaryCofan.inl c) (BinaryCofan.inr c)).ι.app { as := right }

Next tactic:
simp
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr :=
    Cocones.ext (Iso.refl _) fun j => by cases' j with l; cases l; repeat 

Proof state:
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y : C
c : BinaryCofan X Y
⊢ c.ι.app { as := right } ≫ (Iso.refl c.pt).hom =
    (BinaryCofan.mk (BinaryCofan.inl c) (BinaryCofan.inr c)).ι.app { as := right }

Next tactic:
simp
/-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/
def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr :=
    Cocones.ext (Iso.refl _) fun j => by cases' j with l; cases l; repeat 

Proof state:

Next tactic:
simp
/-- This is a more convenient formulation to show that a `BinaryFan` constructed using
`BinaryFan.mk` is a limit cone.
-/
def BinaryFan.isLimitMk {W : C} {fst : W ⟶ X} {snd : W ⟶ Y} (lift : ∀ s : BinaryFan X Y, s.pt ⟶ W)
    (fac_left : ∀ s : BinaryFan X Y, lift s ≫ fst = s.fst)
    (fac_right : ∀ s : BinaryFan X Y, lift s ≫ snd = s.snd)
    (uniq :
      ∀ (s : BinaryFan X Y) (m : s.pt ⟶ W) (_ : m ≫ fst = s.fst) (_ : m ≫ snd = s.snd),
        m = lift s) :
    IsLimit (BinaryFan.mk fst snd) :=
  { lift := lift
    fac := fun s j => by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y W : C
fst : W ⟶ X
snd : W ⟶ Y
lift : (s : BinaryFan X Y) → s.pt ⟶ W
fac_left : ∀ (s : BinaryFan X Y), lift s ≫ fst = CategoryTheory.Limits.BinaryFan.fst s
fac_right : ∀ (s : BinaryFan X Y), lift s ≫ snd = CategoryTheory.Limits.BinaryFan.snd s
uniq :
  ∀ (s : BinaryFan X Y) (m : s.pt ⟶ W),
    m ≫ fst = CategoryTheory.Limits.BinaryFan.fst s → m ≫ snd = CategoryTheory.Limits.BinaryFan.snd s → m = lift s
s : Cone (pair X Y)
j : Discrete WalkingPair
⊢ lift s ≫ (mk fst snd).π.app j = s.π.app j

Next tactic:
rcases j with ⟨⟨⟩⟩
/-- This is a more convenient formulation to show that a `BinaryFan` constructed using
`BinaryFan.mk` is a limit cone.
-/
def BinaryFan.isLimitMk {W : C} {fst : W ⟶ X} {snd : W ⟶ Y} (lift : ∀ s : BinaryFan X Y, s.pt ⟶ W)
    (fac_left : ∀ s : BinaryFan X Y, lift s ≫ fst = s.fst)
    (fac_right : ∀ s : BinaryFan X Y, lift s ≫ snd = s.snd)
    (uniq :
      ∀ (s : BinaryFan X Y) (m : s.pt ⟶ W) (_ : m ≫ fst = s.fst) (_ : m ≫ snd = s.snd),
        m = lift s) :
    IsLimit (BinaryFan.mk fst snd) :=
  { lift := lift
    fac := fun s j => by
      rcases j with ⟨⟨⟩⟩
      

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X Y W : C
fst : W ⟶ X
snd : W ⟶ Y
lift : (s : BinaryFan X Y) → s.pt ⟶ W
fac_left : ∀ (s : BinaryFan X Y), lift s ≫ fst = CategoryTheory.Limits.BinaryFan.fst s
fac_right : ∀ (s : BinaryFan X Y), lift s ≫ snd = CategoryTheory.Limits.BinaryFan.snd s
uniq :
  ∀ (s : BinaryFan X Y) (m : s.pt ⟶ W),
    m ≫ fst = CategoryTheory.Limits.BinaryFan.fst s → m ≫ snd = CategoryTheory.Limits.BinaryFan.snd s → m = lift s
s : Cone (pair X Y)
⊢ lift s ≫ (mk fst snd).π.app { as := left } = s.π.app { as := left }
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X Y W : C
fst : W ⟶ X
snd : W ⟶ Y
lift : (s : BinaryFan X Y) → s.pt ⟶ W
fac_left : ∀ (s : BinaryFan X Y), lift s ≫ fst = CategoryTheory.Limits.BinaryFan.fst s
fac_right : ∀ (s : BinaryFan X Y), lift s ≫ snd = CategoryTheory.Limits.BinaryFan.snd s
uniq :
  ∀ (s : BinaryFan X Y) (m : s.pt ⟶ W),
    m ≫ fst = CategoryTheory.Limits.BinaryFan.fst s → m ≫ snd = CategoryTheory.Limits.BinaryFan.snd s → m = lift s
s : Cone (pair X Y)
⊢ lift s ≫ (mk fst snd).π.app { as := right } = s.π.app { as := right }

Next tactic:
exacts [fac_left s, fac_right s]
/-- This is a more convenient formulation to show that a `BinaryCofan` constructed using
`BinaryCofan.mk` is a colimit cocone.
-/
def BinaryCofan.isColimitMk {W : C} {inl : X ⟶ W} {inr : Y ⟶ W}
    (desc : ∀ s : BinaryCofan X Y, W ⟶ s.pt)
    (fac_left : ∀ s : BinaryCofan X Y, inl ≫ desc s = s.inl)
    (fac_right : ∀ s : BinaryCofan X Y, inr ≫ desc s = s.inr)
    (uniq :
      ∀ (s : BinaryCofan X Y) (m : W ⟶ s.pt) (_ : inl ≫ m = s.inl) (_ : inr ≫ m = s.inr),
        m = desc s) :
    IsColimit (BinaryCofan.mk inl inr) :=
  { desc := desc
    fac := fun s j => by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y W : C
inl : X ⟶ W
inr : Y ⟶ W
desc : (s : BinaryCofan X Y) → W ⟶ s.pt
fac_left : ∀ (s : BinaryCofan X Y), inl ≫ desc s = CategoryTheory.Limits.BinaryCofan.inl s
fac_right : ∀ (s : BinaryCofan X Y), inr ≫ desc s = CategoryTheory.Limits.BinaryCofan.inr s
uniq :
  ∀ (s : BinaryCofan X Y) (m : W ⟶ s.pt),
    inl ≫ m = CategoryTheory.Limits.BinaryCofan.inl s → inr ≫ m = CategoryTheory.Limits.BinaryCofan.inr s → m = desc s
s : Cocone (pair X Y)
j : Discrete WalkingPair
⊢ (mk inl inr).ι.app j ≫ desc s = s.ι.app j

Next tactic:
rcases j with ⟨⟨⟩⟩
/-- This is a more convenient formulation to show that a `BinaryCofan` constructed using
`BinaryCofan.mk` is a colimit cocone.
-/
def BinaryCofan.isColimitMk {W : C} {inl : X ⟶ W} {inr : Y ⟶ W}
    (desc : ∀ s : BinaryCofan X Y, W ⟶ s.pt)
    (fac_left : ∀ s : BinaryCofan X Y, inl ≫ desc s = s.inl)
    (fac_right : ∀ s : BinaryCofan X Y, inr ≫ desc s = s.inr)
    (uniq :
      ∀ (s : BinaryCofan X Y) (m : W ⟶ s.pt) (_ : inl ≫ m = s.inl) (_ : inr ≫ m = s.inr),
        m = desc s) :
    IsColimit (BinaryCofan.mk inl inr) :=
  { desc := desc
    fac := fun s j => by
      rcases j with ⟨⟨⟩⟩
      

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X Y W : C
inl : X ⟶ W
inr : Y ⟶ W
desc : (s : BinaryCofan X Y) → W ⟶ s.pt
fac_left : ∀ (s : BinaryCofan X Y), inl ≫ desc s = CategoryTheory.Limits.BinaryCofan.inl s
fac_right : ∀ (s : BinaryCofan X Y), inr ≫ desc s = CategoryTheory.Limits.BinaryCofan.inr s
uniq :
  ∀ (s : BinaryCofan X Y) (m : W ⟶ s.pt),
    inl ≫ m = CategoryTheory.Limits.BinaryCofan.inl s → inr ≫ m = CategoryTheory.Limits.BinaryCofan.inr s → m = desc s
s : Cocone (pair X Y)
⊢ (mk inl inr).ι.app { as := left } ≫ desc s = s.ι.app { as := left }
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X Y W : C
inl : X ⟶ W
inr : Y ⟶ W
desc : (s : BinaryCofan X Y) → W ⟶ s.pt
fac_left : ∀ (s : BinaryCofan X Y), inl ≫ desc s = CategoryTheory.Limits.BinaryCofan.inl s
fac_right : ∀ (s : BinaryCofan X Y), inr ≫ desc s = CategoryTheory.Limits.BinaryCofan.inr s
uniq :
  ∀ (s : BinaryCofan X Y) (m : W ⟶ s.pt),
    inl ≫ m = CategoryTheory.Limits.BinaryCofan.inl s → inr ≫ m = CategoryTheory.Limits.BinaryCofan.inr s → m = desc s
s : Cocone (pair X Y)
⊢ (mk inl inr).ι.app { as := right } ≫ desc s = s.ι.app { as := right }

Next tactic:
exacts [fac_left s, fac_right s]