l3lab/ntp-mathlib huggingface dataset:
theorem zpow_injective (h₀ : 0 < a) (h₁ : a ≠ 1) : Injective (a ^ · : ℤ → α) := by
  rcases h₁.lt_or_lt with (H | H)
  · 

Proof state:
case inl
α : Type u_1
inst✝ : LinearOrderedSemifield α
a b c d e : α
m n : ℤ
h₀ : 0 < a
h₁ : a ≠ 1
H : a < 1
⊢ Injective fun x => a ^ x

Next tactic:
exact (zpow_strictAnti h₀ H).injective
theorem zpow_injective (h₀ : 0 < a) (h₁ : a ≠ 1) : Injective (a ^ · : ℤ → α) := by
  rcases h₁.lt_or_lt with (H | H)
  · exact (zpow_strictAnti h₀ H).injective
  · 

Proof state:
case inr
α : Type u_1
inst✝ : LinearOrderedSemifield α
a b c d e : α
m n : ℤ
h₀ : 0 < a
h₁ : a ≠ 1
H : 1 < a
⊢ Injective fun x => a ^ x

Next tactic:
exact (zpow_strictMono H).injective
theorem zpow_le_max_iff_min_le {x : α} (hx : 1 < x) {a b c : ℤ} :
    x ^ (-c) ≤ max (x ^ (-a)) (x ^ (-b)) ↔ min a b ≤ c := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedSemifield α
a✝ b✝ c✝ d e : α
m n : ℤ
x : α
hx : 1 < x
a b c : ℤ
⊢ x ^ (-c) ≤ max (x ^ (-a)) (x ^ (-b)) ↔ min a b ≤ c

Next tactic:
simp_rw [le_max_iff, min_le_iff, zpow_le_iff_le hx, neg_le_neg_iff]
theorem zpow_two_nonneg (a : α) : 0 ≤ a ^ (2 : ℤ) := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a✝ b c d : α
n : ℤ
a : α
⊢ 0 ≤ a ^ 2

Next tactic:
convert zpow_bit0_nonneg a 1
theorem zpow_two_pos_of_ne_zero (h : a ≠ 0) : 0 < a ^ (2 : ℤ) := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
h : a ≠ 0
⊢ 0 < a ^ 2

Next tactic:
convert zpow_bit0_pos h 1
@[simp]
theorem zpow_bit0_pos_iff (hn : n ≠ 0) : 0 < a ^ bit0 n ↔ a ≠ 0 :=
  ⟨by
    

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hn : n ≠ 0
⊢ 0 < a ^ bit0 n → a ≠ 0

Next tactic:
rintro h rfl
@[simp]
theorem zpow_bit0_pos_iff (hn : n ≠ 0) : 0 < a ^ bit0 n ↔ a ≠ 0 :=
  ⟨by
    rintro h rfl
    

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
b c d : α
n : ℤ
hn : n ≠ 0
h : 0 < 0 ^ bit0 n
⊢ False

Next tactic:
refine' (zero_zpow _ _).not_gt h
@[simp]
theorem zpow_bit0_pos_iff (hn : n ≠ 0) : 0 < a ^ bit0 n ↔ a ≠ 0 :=
  ⟨by
    rintro h rfl
    refine' (zero_zpow _ _).not_gt h
    

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
b c d : α
n : ℤ
hn : n ≠ 0
h : 0 < 0 ^ bit0 n
⊢ bit0 n ≠ 0

Next tactic:
rwa [bit0_ne_zero]
@[simp]
theorem zpow_bit1_neg_iff : a ^ bit1 n < 0 ↔ a < 0 :=
  ⟨fun h => not_le.1 fun h' => not_le.2 h <| zpow_nonneg h' _, fun h => by
    

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
h : a < 0
⊢ a ^ bit1 n < 0

Next tactic:
rw [bit1, zpow_add_one₀ h.ne]
@[simp]
theorem zpow_bit1_neg_iff : a ^ bit1 n < 0 ↔ a < 0 :=
  ⟨fun h => not_le.1 fun h' => not_le.2 h <| zpow_nonneg h' _, fun h => by
    rw [bit1, zpow_add_one₀ h.ne]; 

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
h : a < 0
⊢ a ^ bit0 n * a < 0

Next tactic:
exact mul_neg_of_pos_of_neg (zpow_bit0_pos h.ne _) h
@[simp]
theorem zpow_bit1_nonpos_iff : a ^ bit1 n ≤ 0 ↔ a ≤ 0 := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
⊢ a ^ bit1 n ≤ 0 ↔ a ≤ 0

Next tactic:
rw [le_iff_lt_or_eq, le_iff_lt_or_eq, zpow_bit1_neg_iff, zpow_eq_zero_iff (Int.bit1_ne_zero n)]
protected theorem Even.zpow_nonneg (hn : Even n) (a : α) : 0 ≤ a ^ n := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a✝ b c d : α
n : ℤ
hn : Even n
a : α
⊢ 0 ≤ a ^ n

Next tactic:
obtain ⟨k, rfl⟩ := hn
protected theorem Even.zpow_nonneg (hn : Even n) (a : α) : 0 ≤ a ^ n := by
  obtain ⟨k, rfl⟩ := hn; 

Proof state:
case intro
α : Type u_1
inst✝ : LinearOrderedField α
a✝ b c d a : α
k : ℤ
⊢ 0 ≤ a ^ (k + k)

Next tactic:
exact zpow_bit0_nonneg _ _
theorem Even.zpow_pos_iff (hn : Even n) (h : n ≠ 0) : 0 < a ^ n ↔ a ≠ 0 := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hn : Even n
h : n ≠ 0
⊢ 0 < a ^ n ↔ a ≠ 0

Next tactic:
obtain ⟨k, rfl⟩ := hn
theorem Even.zpow_pos_iff (hn : Even n) (h : n ≠ 0) : 0 < a ^ n ↔ a ≠ 0 := by
  obtain ⟨k, rfl⟩ := hn; 

Proof state:
case intro
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
k : ℤ
h : k + k ≠ 0
⊢ 0 < a ^ (k + k) ↔ a ≠ 0

Next tactic:
exact zpow_bit0_pos_iff (by rintro rfl; simp at h)
theorem Even.zpow_pos_iff (hn : Even n) (h : n ≠ 0) : 0 < a ^ n ↔ a ≠ 0 := by
  obtain ⟨k, rfl⟩ := hn; exact zpow_bit0_pos_iff (by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
k : ℤ
h : k + k ≠ 0
⊢ k ≠ 0

Next tactic:
rintro rfl
theorem Even.zpow_pos_iff (hn : Even n) (h : n ≠ 0) : 0 < a ^ n ↔ a ≠ 0 := by
  obtain ⟨k, rfl⟩ := hn; exact zpow_bit0_pos_iff (by rintro rfl; 

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
h : 0 + 0 ≠ 0
⊢ False

Next tactic:
simp at h
theorem Odd.zpow_neg_iff (hn : Odd n) : a ^ n < 0 ↔ a < 0 := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hn : Odd n
⊢ a ^ n < 0 ↔ a < 0

Next tactic:
cases' hn with k hk
theorem Odd.zpow_neg_iff (hn : Odd n) : a ^ n < 0 ↔ a < 0 := by
  cases' hn with k hk; 

Proof state:
case intro
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n k : ℤ
hk : n = 2 * k + 1
⊢ a ^ n < 0 ↔ a < 0

Next tactic:
simpa only [hk, two_mul] using zpow_bit1_neg_iff
protected theorem Odd.zpow_nonneg_iff (hn : Odd n) : 0 ≤ a ^ n ↔ 0 ≤ a := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hn : Odd n
⊢ 0 ≤ a ^ n ↔ 0 ≤ a

Next tactic:
cases' hn with k hk
protected theorem Odd.zpow_nonneg_iff (hn : Odd n) : 0 ≤ a ^ n ↔ 0 ≤ a := by
  cases' hn with k hk; 

Proof state:
case intro
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n k : ℤ
hk : n = 2 * k + 1
⊢ 0 ≤ a ^ n ↔ 0 ≤ a

Next tactic:
simpa only [hk, two_mul] using zpow_bit1_nonneg_iff
theorem Odd.zpow_nonpos_iff (hn : Odd n) : a ^ n ≤ 0 ↔ a ≤ 0 := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hn : Odd n
⊢ a ^ n ≤ 0 ↔ a ≤ 0

Next tactic:
cases' hn with k hk
theorem Odd.zpow_nonpos_iff (hn : Odd n) : a ^ n ≤ 0 ↔ a ≤ 0 := by
  cases' hn with k hk; 

Proof state:
case intro
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n k : ℤ
hk : n = 2 * k + 1
⊢ a ^ n ≤ 0 ↔ a ≤ 0

Next tactic:
simpa only [hk, two_mul] using zpow_bit1_nonpos_iff
theorem Odd.zpow_pos_iff (hn : Odd n) : 0 < a ^ n ↔ 0 < a := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n : ℤ
hn : Odd n
⊢ 0 < a ^ n ↔ 0 < a

Next tactic:
cases' hn with k hk
theorem Odd.zpow_pos_iff (hn : Odd n) : 0 < a ^ n ↔ 0 < a := by
  cases' hn with k hk; 

Proof state:
case intro
α : Type u_1
inst✝ : LinearOrderedField α
a b c d : α
n k : ℤ
hk : n = 2 * k + 1
⊢ 0 < a ^ n ↔ 0 < a

Next tactic:
simpa only [hk, two_mul] using zpow_bit1_pos_iff
theorem Even.zpow_abs {p : ℤ} (hp : Even p) (a : α) : |a| ^ p = a ^ p := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedField α
a✝ b c d : α
n p : ℤ
hp : Even p
a : α
⊢ |a| ^ p = a ^ p

Next tactic:
cases' abs_choice a with h h
theorem Even.zpow_abs {p : ℤ} (hp : Even p) (a : α) : |a| ^ p = a ^ p := by
  cases' abs_choice a with h h <;> 

Proof state:
case inl
α : Type u_1
inst✝ : LinearOrderedField α
a✝ b c d : α
n p : ℤ
hp : Even p
a : α
h : |a| = a
⊢ |a| ^ p = a ^ p

Next tactic:
simp only [h, hp.neg_zpow _]
theorem Even.zpow_abs {p : ℤ} (hp : Even p) (a : α) : |a| ^ p = a ^ p := by
  cases' abs_choice a with h h <;> 

Proof state:
case inr
α : Type u_1
inst✝ : LinearOrderedField α
a✝ b c d : α
n p : ℤ
hp : Even p
a : α
h : |a| = -a
⊢ |a| ^ p = a ^ p

Next tactic:
simp only [h, hp.neg_zpow _]
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
⊢ (IsLimit.lift h₁ (π₁.mapCone s) ≫ c.pt.f) ≫ (π₂.mapCone c).π.app j =
    (s.pt.f ≫ IsLimit.lift h₂ (π₂.mapCone s)) ≫ (π₂.mapCone c).π.app j

Next tactic:
have eq₁ := h₁.fac (π₁.mapCone s)
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₁ : ∀ (j : J), IsLimit.lift h₁ (π₁.mapCone s) ≫ (π₁.mapCone c).π.app j = (π₁.mapCone s).π.app j
⊢ (IsLimit.lift h₁ (π₁.mapCone s) ≫ c.pt.f) ≫ (π₂.mapCone c).π.app j =
    (s.pt.f ≫ IsLimit.lift h₂ (π₂.mapCone s)) ≫ (π₂.mapCone c).π.app j

Next tactic:
have eq₂ := h₂.fac (π₂.mapCone s)
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₁ : ∀ (j : J), IsLimit.lift h₁ (π₁.mapCone s) ≫ (π₁.mapCone c).π.app j = (π₁.mapCone s).π.app j
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (π₂.mapCone c).π.app j = (π₂.mapCone s).π.app j
⊢ (IsLimit.lift h₁ (π₁.mapCone s) ≫ c.pt.f) ≫ (π₂.mapCone c).π.app j =
    (s.pt.f ≫ IsLimit.lift h₂ (π₂.mapCone s)) ≫ (π₂.mapCone c).π.app j

Next tactic:
have eq₁₂ := fun j => (c.π.app j).comm₁₂
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₁ : ∀ (j : J), IsLimit.lift h₁ (π₁.mapCone s) ≫ (π₁.mapCone c).π.app j = (π₁.mapCone s).π.app j
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (π₂.mapCone c).π.app j = (π₂.mapCone s).π.app j
eq₁₂ : ∀ (j : J), (c.π.app j).τ₁ ≫ (F.obj j).f = (((Functor.const J).obj c.pt).obj j).f ≫ (c.π.app j).τ₂
⊢ (IsLimit.lift h₁ (π₁.mapCone s) ≫ c.pt.f) ≫ (π₂.mapCone c).π.app j =
    (s.pt.f ≫ IsLimit.lift h₂ (π₂.mapCone s)) ≫ (π₂.mapCone c).π.app j

Next tactic:
have eq₁₂' := fun j => (s.π.app j).comm₁₂
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        have eq₁₂' := fun j => (s.π.app j).comm₁₂
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₁ : ∀ (j : J), IsLimit.lift h₁ (π₁.mapCone s) ≫ (π₁.mapCone c).π.app j = (π₁.mapCone s).π.app j
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (π₂.mapCone c).π.app j = (π₂.mapCone s).π.app j
eq₁₂ : ∀ (j : J), (c.π.app j).τ₁ ≫ (F.obj j).f = (((Functor.const J).obj c.pt).obj j).f ≫ (c.π.app j).τ₂
eq₁₂' : ∀ (j : J), (s.π.app j).τ₁ ≫ (F.obj j).f = (((Functor.const J).obj s.pt).obj j).f ≫ (s.π.app j).τ₂
⊢ (IsLimit.lift h₁ (π₁.mapCone s) ≫ c.pt.f) ≫ (π₂.mapCone c).π.app j =
    (s.pt.f ≫ IsLimit.lift h₂ (π₂.mapCone s)) ≫ (π₂.mapCone c).π.app j

Next tactic:
dsimp at eq₁ eq₂ eq₁₂ eq₁₂' ⊢
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        have eq₁₂' := fun j => (s.π.app j).comm₁₂
        dsimp at eq₁ eq₂ eq₁₂ eq₁₂' ⊢
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₁ : ∀ (j : J), IsLimit.lift h₁ (π₁.mapCone s) ≫ (c.π.app j).τ₁ = (s.π.app j).τ₁
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (c.π.app j).τ₂ = (s.π.app j).τ₂
eq₁₂ : ∀ (j : J), (c.π.app j).τ₁ ≫ (F.obj j).f = c.pt.f ≫ (c.π.app j).τ₂
eq₁₂' : ∀ (j : J), (s.π.app j).τ₁ ≫ (F.obj j).f = s.pt.f ≫ (s.π.app j).τ₂
⊢ (IsLimit.lift h₁ (π₁.mapCone s) ≫ c.pt.f) ≫ (c.π.app j).τ₂ =
    (s.pt.f ≫ IsLimit.lift h₂ (π₂.mapCone s)) ≫ (c.π.app j).τ₂

Next tactic:
rw [assoc, assoc, ← eq₁₂, reassoc_of% eq₁, eq₂, eq₁₂']
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        have eq₁₂' := fun j => (s.π.app j).comm₁₂
        dsimp at eq₁ eq₂ eq₁₂ eq₁₂' ⊢
        rw [assoc, assoc, ← eq₁₂, reassoc_of% eq₁, eq₂, eq₁₂'])
      comm₂₃ := h₃.hom_ext (fun j => by
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
⊢ (IsLimit.lift h₂ (π₂.mapCone s) ≫ c.pt.g) ≫ (π₃.mapCone c).π.app j =
    (s.pt.g ≫ IsLimit.lift h₃ (π₃.mapCone s)) ≫ (π₃.mapCone c).π.app j

Next tactic:
have eq₂ := h₂.fac (π₂.mapCone s)
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        have eq₁₂' := fun j => (s.π.app j).comm₁₂
        dsimp at eq₁ eq₂ eq₁₂ eq₁₂' ⊢
        rw [assoc, assoc, ← eq₁₂, reassoc_of% eq₁, eq₂, eq₁₂'])
      comm₂₃ := h₃.hom_ext (fun j => by
        have eq₂ := h₂.fac (π₂.mapCone s)
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (π₂.mapCone c).π.app j = (π₂.mapCone s).π.app j
⊢ (IsLimit.lift h₂ (π₂.mapCone s) ≫ c.pt.g) ≫ (π₃.mapCone c).π.app j =
    (s.pt.g ≫ IsLimit.lift h₃ (π₃.mapCone s)) ≫ (π₃.mapCone c).π.app j

Next tactic:
have eq₃ := h₃.fac (π₃.mapCone s)
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        have eq₁₂' := fun j => (s.π.app j).comm₁₂
        dsimp at eq₁ eq₂ eq₁₂ eq₁₂' ⊢
        rw [assoc, assoc, ← eq₁₂, reassoc_of% eq₁, eq₂, eq₁₂'])
      comm₂₃ := h₃.hom_ext (fun j => by
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₃ := h₃.fac (π₃.mapCone s)
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (π₂.mapCone c).π.app j = (π₂.mapCone s).π.app j
eq₃ : ∀ (j : J), IsLimit.lift h₃ (π₃.mapCone s) ≫ (π₃.mapCone c).π.app j = (π₃.mapCone s).π.app j
⊢ (IsLimit.lift h₂ (π₂.mapCone s) ≫ c.pt.g) ≫ (π₃.mapCone c).π.app j =
    (s.pt.g ≫ IsLimit.lift h₃ (π₃.mapCone s)) ≫ (π₃.mapCone c).π.app j

Next tactic:
have eq₂₃ := fun j => (c.π.app j).comm₂₃
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        have eq₁₂' := fun j => (s.π.app j).comm₁₂
        dsimp at eq₁ eq₂ eq₁₂ eq₁₂' ⊢
        rw [assoc, assoc, ← eq₁₂, reassoc_of% eq₁, eq₂, eq₁₂'])
      comm₂₃ := h₃.hom_ext (fun j => by
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₃ := h₃.fac (π₃.mapCone s)
        have eq₂₃ := fun j => (c.π.app j).comm₂₃
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (π₂.mapCone c).π.app j = (π₂.mapCone s).π.app j
eq₃ : ∀ (j : J), IsLimit.lift h₃ (π₃.mapCone s) ≫ (π₃.mapCone c).π.app j = (π₃.mapCone s).π.app j
eq₂₃ : ∀ (j : J), (c.π.app j).τ₂ ≫ (F.obj j).g = (((Functor.const J).obj c.pt).obj j).g ≫ (c.π.app j).τ₃
⊢ (IsLimit.lift h₂ (π₂.mapCone s) ≫ c.pt.g) ≫ (π₃.mapCone c).π.app j =
    (s.pt.g ≫ IsLimit.lift h₃ (π₃.mapCone s)) ≫ (π₃.mapCone c).π.app j

Next tactic:
have eq₂₃' := fun j => (s.π.app j).comm₂₃
/-- If a cone with values in `ShortComplex C` is such that it becomes limit
when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/
def isLimitOfIsLimitπ (c : Cone F)
    (h₁ : IsLimit (π₁.mapCone c)) (h₂ : IsLimit (π₂.mapCone c))
    (h₃ : IsLimit (π₃.mapCone c)) : IsLimit c where
  lift s :=
    { τ₁ := h₁.lift (π₁.mapCone s)
      τ₂ := h₂.lift (π₂.mapCone s)
      τ₃ := h₃.lift (π₃.mapCone s)
      comm₁₂ := h₂.hom_ext (fun j => by
        have eq₁ := h₁.fac (π₁.mapCone s)
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₁₂ := fun j => (c.π.app j).comm₁₂
        have eq₁₂' := fun j => (s.π.app j).comm₁₂
        dsimp at eq₁ eq₂ eq₁₂ eq₁₂' ⊢
        rw [assoc, assoc, ← eq₁₂, reassoc_of% eq₁, eq₂, eq₁₂'])
      comm₂₃ := h₃.hom_ext (fun j => by
        have eq₂ := h₂.fac (π₂.mapCone s)
        have eq₃ := h₃.fac (π₃.mapCone s)
        have eq₂₃ := fun j => (c.π.app j).comm₂₃
        have eq₂₃' := fun j => (s.π.app j).comm₂₃
        

Proof state:
J : Type u_1
C : Type u_2
inst✝² : Category.{?u.96, u_1} J
inst✝¹ : Category.{?u.100, u_2} C
inst✝ : HasZeroMorphisms C
F : J ⥤ ShortComplex C
c : Cone F
h₁ : IsLimit (π₁.mapCone c)
h₂ : IsLimit (π₂.mapCone c)
h₃ : IsLimit (π₃.mapCone c)
s : Cone F
j : J
eq₂ : ∀ (j : J), IsLimit.lift h₂ (π₂.mapCone s) ≫ (π₂.mapCone c).π.app j = (π₂.mapCone s).π.app j
eq₃ : ∀ (j : J), IsLimit.lift h₃ (π₃.mapCone s) ≫ (π₃.mapCone c).π.app j = (π₃.mapCone s).π.app j
eq₂₃ : ∀ (j : J), (c.π.app j).τ₂ ≫ (F.obj j).g = (((Functor.const J).obj c.pt).obj j).g ≫ (c.π.app j).τ₃
eq₂₃' : ∀ (j : J), (s.π.app j).τ₂ ≫ (F.obj j).g = (((Functor.const J).obj s.pt).obj j).g ≫ (s.π.app j).τ₃
⊢ (IsLimit.lift h₂ (π₂.mapCone s) ≫ c.pt.g) ≫ (π₃.mapCone c).π.app j =
    (s.pt.g ≫ IsLimit.lift h₃ (π₃.mapCone s)) ≫ (π₃.mapCone c).π.app j

Next tactic:
dsimp at eq₂ eq₃ eq₂₃ eq₂₃' ⊢