l3lab/ntp-mathlib huggingface dataset:
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> 

Proof state:
case mk.right.mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
⊢ (lift R (BinaryFan.assocInv P t) ≫ lift Q (BinaryFan.mk (BinaryFan.fst s ≫ BinaryFan.snd sXY) (BinaryFan.snd s))) ≫
      sYZ.π.app { as := WalkingPair.left } =
    BinaryFan.snd t ≫ sYZ.π.app { as := WalkingPair.left }

Next tactic:
simp
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> 

Proof state:
case mk.right.mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
⊢ (lift R (BinaryFan.assocInv P t) ≫ lift Q (BinaryFan.mk (BinaryFan.fst s ≫ BinaryFan.snd sXY) (BinaryFan.snd s))) ≫
      sYZ.π.app { as := WalkingPair.right } =
    BinaryFan.snd t ≫ sYZ.π.app { as := WalkingPair.right }

Next tactic:
simp
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
⊢ m = (fun t => lift R (BinaryFan.assocInv P t)) t

Next tactic:
have h := R.uniq (BinaryFan.assocInv P t) m
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m = (fun t => lift R (BinaryFan.assocInv P t)) t

Next tactic:
rw [h]
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ ∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j

Next tactic:
rintro ⟨⟨⟩⟩
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> 

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m ≫ s.π.app { as := WalkingPair.left } = (BinaryFan.assocInv P t).π.app { as := WalkingPair.left }

Next tactic:
simp
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> 

Proof state:
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m ≫ s.π.app { as := WalkingPair.right } = (BinaryFan.assocInv P t).π.app { as := WalkingPair.right }

Next tactic:
simp
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m ≫ BinaryFan.fst s = lift P (BinaryFan.mk (BinaryFan.fst t) (BinaryFan.snd t ≫ BinaryFan.fst sYZ))
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m ≫ BinaryFan.snd s = BinaryFan.snd t ≫ BinaryFan.snd sYZ

Next tactic:
apply P.hom_ext
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    

Proof state:
case mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ ∀ (j : Discrete WalkingPair),
    (m ≫ BinaryFan.fst s) ≫ sXY.π.app j =
      lift P (BinaryFan.mk (BinaryFan.fst t) (BinaryFan.snd t ≫ BinaryFan.fst sYZ)) ≫ sXY.π.app j

Next tactic:
rintro ⟨⟨⟩⟩
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> 

Proof state:
case mk.left.mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ (m ≫ BinaryFan.fst s) ≫ sXY.π.app { as := WalkingPair.left } =
    lift P (BinaryFan.mk (BinaryFan.fst t) (BinaryFan.snd t ≫ BinaryFan.fst sYZ)) ≫ sXY.π.app { as := WalkingPair.left }

Next tactic:
simp
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> 

Proof state:
case mk.left.mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ (m ≫ BinaryFan.fst s) ≫ sXY.π.app { as := WalkingPair.right } =
    lift P (BinaryFan.mk (BinaryFan.fst t) (BinaryFan.snd t ≫ BinaryFan.fst sYZ)) ≫
      sXY.π.app { as := WalkingPair.right }

Next tactic:
simp
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · 

Proof state:
case mk.left.mk.left
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m ≫ BinaryFan.fst s ≫ BinaryFan.fst sXY = BinaryFan.fst t

Next tactic:
exact w ⟨WalkingPair.left⟩
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · exact w ⟨WalkingPair.left⟩
    · 

Proof state:
case mk.left.mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m ≫ BinaryFan.fst s ≫ BinaryFan.snd sXY = BinaryFan.snd t ≫ BinaryFan.fst sYZ

Next tactic:
specialize w ⟨WalkingPair.right⟩
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · exact w ⟨WalkingPair.left⟩
    · specialize w ⟨WalkingPair.right⟩
      

Proof state:
case mk.left.mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
w : m ≫ (BinaryFan.assoc Q s).π.app { as := WalkingPair.right } = t.π.app { as := WalkingPair.right }
⊢ m ≫ BinaryFan.fst s ≫ BinaryFan.snd sXY = BinaryFan.snd t ≫ BinaryFan.fst sYZ

Next tactic:
simp? at w says
        simp only [pair_obj_right, BinaryFan.π_app_right, BinaryFan.assoc_snd,
          Functor.const_obj_obj, pair_obj_left] at w
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · exact w ⟨WalkingPair.left⟩
    · specialize w ⟨WalkingPair.right⟩
      simp? at w says
        

Proof state:
case mk.left.mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
w : m ≫ (BinaryFan.assoc Q s).π.app { as := WalkingPair.right } = t.π.app { as := WalkingPair.right }
⊢ m ≫ BinaryFan.fst s ≫ BinaryFan.snd sXY = BinaryFan.snd t ≫ BinaryFan.fst sYZ

Next tactic:
simp only [pair_obj_right, BinaryFan.π_app_right, BinaryFan.assoc_snd,
          Functor.const_obj_obj, pair_obj_left] at w
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · exact w ⟨WalkingPair.left⟩
    · specialize w ⟨WalkingPair.right⟩
      simp? at w says
        simp only [pair_obj_right, BinaryFan.π_app_right, BinaryFan.assoc_snd,
          Functor.const_obj_obj, pair_obj_left] at w
      

Proof state:
case mk.left.mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
w : m ≫ lift Q (BinaryFan.mk (BinaryFan.fst s ≫ BinaryFan.snd sXY) (BinaryFan.snd s)) = BinaryFan.snd t
⊢ m ≫ BinaryFan.fst s ≫ BinaryFan.snd sXY = BinaryFan.snd t ≫ BinaryFan.fst sYZ

Next tactic:
rw [← w]
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · exact w ⟨WalkingPair.left⟩
    · specialize w ⟨WalkingPair.right⟩
      simp? at w says
        simp only [pair_obj_right, BinaryFan.π_app_right, BinaryFan.assoc_snd,
          Functor.const_obj_obj, pair_obj_left] at w
      rw [← w]
      

Proof state:
case mk.left.mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
w : m ≫ lift Q (BinaryFan.mk (BinaryFan.fst s ≫ BinaryFan.snd sXY) (BinaryFan.snd s)) = BinaryFan.snd t
⊢ m ≫ BinaryFan.fst s ≫ BinaryFan.snd sXY =
    (m ≫ lift Q (BinaryFan.mk (BinaryFan.fst s ≫ BinaryFan.snd sXY) (BinaryFan.snd s))) ≫ BinaryFan.fst sYZ

Next tactic:
simp
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · exact w ⟨WalkingPair.left⟩
    · specialize w ⟨WalkingPair.right⟩
      simp? at w says
        simp only [pair_obj_right, BinaryFan.π_app_right, BinaryFan.assoc_snd,
          Functor.const_obj_obj, pair_obj_left] at w
      rw [← w]
      simp
    · 

Proof state:
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
w : ∀ (j : Discrete WalkingPair), m ≫ (BinaryFan.assoc Q s).π.app j = t.π.app j
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
⊢ m ≫ BinaryFan.snd s = BinaryFan.snd t ≫ BinaryFan.snd sYZ

Next tactic:
specialize w ⟨WalkingPair.right⟩
/-- If all the binary fans involved a limit cones, `BinaryFan.assoc` produces another limit cone.
-/
@[simps]
def IsLimit.assoc {X Y Z : C} {sXY : BinaryFan X Y} (P : IsLimit sXY) {sYZ : BinaryFan Y Z}
    (Q : IsLimit sYZ) {s : BinaryFan sXY.pt Z} (R : IsLimit s) : IsLimit (BinaryFan.assoc Q s) where
  lift t := R.lift (BinaryFan.assocInv P t)
  fac t := by
    rintro ⟨⟨⟩⟩ <;> simp
    apply Q.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
  uniq t m w := by
    have h := R.uniq (BinaryFan.assocInv P t) m
    rw [h]
    rintro ⟨⟨⟩⟩ <;> simp
    apply P.hom_ext
    rintro ⟨⟨⟩⟩ <;> simp
    · exact w ⟨WalkingPair.left⟩
    · specialize w ⟨WalkingPair.right⟩
      simp? at w says
        simp only [pair_obj_right, BinaryFan.π_app_right, BinaryFan.assoc_snd,
          Functor.const_obj_obj, pair_obj_left] at w
      rw [← w]
      simp
    · specialize w ⟨WalkingPair.right⟩
      

Proof state:
case mk.right
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ X Y Z : C
sXY : BinaryFan X Y
P : IsLimit sXY
sYZ : BinaryFan Y Z
Q : IsLimit sYZ
s : BinaryFan sXY.pt Z
R : IsLimit s
t : Cone (pair X sYZ.pt)
m : t.pt ⟶ (BinaryFan.assoc Q s).pt
h :
  (∀ (j : Discrete WalkingPair), m ≫ s.π.app j = (BinaryFan.assocInv P t).π.app j) → m = lift R (BinaryFan.assocInv P t)
w : m ≫ (BinaryFan.assoc Q s).π.app { as := WalkingPair.right } = t.π.app { as := WalkingPair.right }
⊢ m ≫ BinaryFan.snd s = BinaryFan.snd t ≫ BinaryFan.snd sYZ

Next tactic:
simp? at w says
        simp only [pair_obj_right, BinaryFan.π_app_right, BinaryFan.assoc_snd,
          Functor.const_obj_obj, pair_obj_left] at w