l3lab/ntp-mathlib huggingface dataset:
theorem hasStrictDerivAt_zpow (m : ℤ) (x : 𝕜) (h : x ≠ 0 ∨ 0 ≤ m) :
    HasStrictDerivAt (fun x => x ^ m) ((m : 𝕜) * x ^ (m - 1)) x := by
  have : ∀ m : ℤ, 0 < m → HasStrictDerivAt (· ^ m) ((m : 𝕜) * x ^ (m - 1)) x := fun m hm ↦ by
    lift m to ℕ using hm.le
    simp only [zpow_ofNat, Int.cast_ofNat]
    convert hasStrictDerivAt_pow m x using 2
    rw [← Int.ofNat_one, ← Int.ofNat_sub, zpow_ofNat]
    norm_cast at hm
  rcases lt_trichotomy m 0 with (hm | hm | hm)
  · have hx : x ≠ 0 := h.resolve_right hm.not_le
    have := (hasStrictDerivAt_inv ?_).scomp _ (this (-m) (neg_pos.2 hm)) <;>
      [skip; exact zpow_ne_zero_of_ne_zero hx _]
    simp only [(· ∘ ·), zpow_neg, one_div, inv_inv, smul_eq_mul] at this
    convert this using 1
    rw [sq, mul_inv, inv_inv, Int.cast_neg, neg_mul, neg_mul_neg, ← zpow_add₀ hx, mul_assoc, ←
      zpow_add₀ hx]
    

Proof state:
case h.e'_7
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
h : x ≠ 0 ∨ 0 ≤ m
this✝ : ∀ (m : ℤ), 0 < m → HasStrictDerivAt (fun x => x ^ m) (↑m * x ^ (m - 1)) x
hm : m < 0
hx : x ≠ 0
this : HasStrictDerivAt (fun x => x ^ m) (↑(-m) * x ^ (-m - 1) * -((x ^ m)⁻¹ ^ 2)⁻¹) x
⊢ ↑m * x ^ (m - 1) = ↑m * x ^ (-m - 1 + (m + m))

Next tactic:
congr
theorem hasStrictDerivAt_zpow (m : ℤ) (x : 𝕜) (h : x ≠ 0 ∨ 0 ≤ m) :
    HasStrictDerivAt (fun x => x ^ m) ((m : 𝕜) * x ^ (m - 1)) x := by
  have : ∀ m : ℤ, 0 < m → HasStrictDerivAt (· ^ m) ((m : 𝕜) * x ^ (m - 1)) x := fun m hm ↦ by
    lift m to ℕ using hm.le
    simp only [zpow_ofNat, Int.cast_ofNat]
    convert hasStrictDerivAt_pow m x using 2
    rw [← Int.ofNat_one, ← Int.ofNat_sub, zpow_ofNat]
    norm_cast at hm
  rcases lt_trichotomy m 0 with (hm | hm | hm)
  · have hx : x ≠ 0 := h.resolve_right hm.not_le
    have := (hasStrictDerivAt_inv ?_).scomp _ (this (-m) (neg_pos.2 hm)) <;>
      [skip; exact zpow_ne_zero_of_ne_zero hx _]
    simp only [(· ∘ ·), zpow_neg, one_div, inv_inv, smul_eq_mul] at this
    convert this using 1
    rw [sq, mul_inv, inv_inv, Int.cast_neg, neg_mul, neg_mul_neg, ← zpow_add₀ hx, mul_assoc, ←
      zpow_add₀ hx]
    congr
    

Proof state:
case h.e'_7.e_a.e_a
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
h : x ≠ 0 ∨ 0 ≤ m
this✝ : ∀ (m : ℤ), 0 < m → HasStrictDerivAt (fun x => x ^ m) (↑m * x ^ (m - 1)) x
hm : m < 0
hx : x ≠ 0
this : HasStrictDerivAt (fun x => x ^ m) (↑(-m) * x ^ (-m - 1) * -((x ^ m)⁻¹ ^ 2)⁻¹) x
⊢ m - 1 = -m - 1 + (m + m)

Next tactic:
abel
theorem hasStrictDerivAt_zpow (m : ℤ) (x : 𝕜) (h : x ≠ 0 ∨ 0 ≤ m) :
    HasStrictDerivAt (fun x => x ^ m) ((m : 𝕜) * x ^ (m - 1)) x := by
  have : ∀ m : ℤ, 0 < m → HasStrictDerivAt (· ^ m) ((m : 𝕜) * x ^ (m - 1)) x := fun m hm ↦ by
    lift m to ℕ using hm.le
    simp only [zpow_ofNat, Int.cast_ofNat]
    convert hasStrictDerivAt_pow m x using 2
    rw [← Int.ofNat_one, ← Int.ofNat_sub, zpow_ofNat]
    norm_cast at hm
  rcases lt_trichotomy m 0 with (hm | hm | hm)
  · have hx : x ≠ 0 := h.resolve_right hm.not_le
    have := (hasStrictDerivAt_inv ?_).scomp _ (this (-m) (neg_pos.2 hm)) <;>
      [skip; exact zpow_ne_zero_of_ne_zero hx _]
    simp only [(· ∘ ·), zpow_neg, one_div, inv_inv, smul_eq_mul] at this
    convert this using 1
    rw [sq, mul_inv, inv_inv, Int.cast_neg, neg_mul, neg_mul_neg, ← zpow_add₀ hx, mul_assoc, ←
      zpow_add₀ hx]
    congr
    abel
  · 

Proof state:
case inr.inl
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
h : x ≠ 0 ∨ 0 ≤ m
this : ∀ (m : ℤ), 0 < m → HasStrictDerivAt (fun x => x ^ m) (↑m * x ^ (m - 1)) x
hm : m = 0
⊢ HasStrictDerivAt (fun x => x ^ m) (↑m * x ^ (m - 1)) x

Next tactic:
simp only [hm, zpow_zero, Int.cast_zero, zero_mul, hasStrictDerivAt_const]
theorem hasStrictDerivAt_zpow (m : ℤ) (x : 𝕜) (h : x ≠ 0 ∨ 0 ≤ m) :
    HasStrictDerivAt (fun x => x ^ m) ((m : 𝕜) * x ^ (m - 1)) x := by
  have : ∀ m : ℤ, 0 < m → HasStrictDerivAt (· ^ m) ((m : 𝕜) * x ^ (m - 1)) x := fun m hm ↦ by
    lift m to ℕ using hm.le
    simp only [zpow_ofNat, Int.cast_ofNat]
    convert hasStrictDerivAt_pow m x using 2
    rw [← Int.ofNat_one, ← Int.ofNat_sub, zpow_ofNat]
    norm_cast at hm
  rcases lt_trichotomy m 0 with (hm | hm | hm)
  · have hx : x ≠ 0 := h.resolve_right hm.not_le
    have := (hasStrictDerivAt_inv ?_).scomp _ (this (-m) (neg_pos.2 hm)) <;>
      [skip; exact zpow_ne_zero_of_ne_zero hx _]
    simp only [(· ∘ ·), zpow_neg, one_div, inv_inv, smul_eq_mul] at this
    convert this using 1
    rw [sq, mul_inv, inv_inv, Int.cast_neg, neg_mul, neg_mul_neg, ← zpow_add₀ hx, mul_assoc, ←
      zpow_add₀ hx]
    congr
    abel
  · simp only [hm, zpow_zero, Int.cast_zero, zero_mul, hasStrictDerivAt_const]
  · 

Proof state:
case inr.inr
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
h : x ≠ 0 ∨ 0 ≤ m
this : ∀ (m : ℤ), 0 < m → HasStrictDerivAt (fun x => x ^ m) (↑m * x ^ (m - 1)) x
hm : 0 < m
⊢ HasStrictDerivAt (fun x => x ^ m) (↑m * x ^ (m - 1)) x

Next tactic:
exact this m hm
theorem deriv_zpow (m : ℤ) (x : 𝕜) : deriv (fun x => x ^ m) x = m * x ^ (m - 1) := by
  

Proof state:
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
⊢ deriv (fun x => x ^ m) x = ↑m * x ^ (m - 1)

Next tactic:
by_cases H : x ≠ 0 ∨ 0 ≤ m
theorem deriv_zpow (m : ℤ) (x : 𝕜) : deriv (fun x => x ^ m) x = m * x ^ (m - 1) := by
  by_cases H : x ≠ 0 ∨ 0 ≤ m
  · 

Proof state:
case pos
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
H : x ≠ 0 ∨ 0 ≤ m
⊢ deriv (fun x => x ^ m) x = ↑m * x ^ (m - 1)

Next tactic:
exact (hasDerivAt_zpow m x H).deriv
theorem deriv_zpow (m : ℤ) (x : 𝕜) : deriv (fun x => x ^ m) x = m * x ^ (m - 1) := by
  by_cases H : x ≠ 0 ∨ 0 ≤ m
  · exact (hasDerivAt_zpow m x H).deriv
  · 

Proof state:
case neg
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
H : ¬(x ≠ 0 ∨ 0 ≤ m)
⊢ deriv (fun x => x ^ m) x = ↑m * x ^ (m - 1)

Next tactic:
rw [deriv_zero_of_not_differentiableAt (mt differentiableAt_zpow.1 H)]
theorem deriv_zpow (m : ℤ) (x : 𝕜) : deriv (fun x => x ^ m) x = m * x ^ (m - 1) := by
  by_cases H : x ≠ 0 ∨ 0 ≤ m
  · exact (hasDerivAt_zpow m x H).deriv
  · rw [deriv_zero_of_not_differentiableAt (mt differentiableAt_zpow.1 H)]
    

Proof state:
case neg
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
H : ¬(x ≠ 0 ∨ 0 ≤ m)
⊢ 0 = ↑m * x ^ (m - 1)

Next tactic:
push_neg at H
theorem deriv_zpow (m : ℤ) (x : 𝕜) : deriv (fun x => x ^ m) x = m * x ^ (m - 1) := by
  by_cases H : x ≠ 0 ∨ 0 ≤ m
  · exact (hasDerivAt_zpow m x H).deriv
  · rw [deriv_zero_of_not_differentiableAt (mt differentiableAt_zpow.1 H)]
    push_neg at H
    

Proof state:
case neg
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m✝ m : ℤ
x : 𝕜
H : x = 0 ∧ m < 0
⊢ 0 = ↑m * x ^ (m - 1)

Next tactic:
rcases H with ⟨rfl, hm⟩
theorem deriv_zpow (m : ℤ) (x : 𝕜) : deriv (fun x => x ^ m) x = m * x ^ (m - 1) := by
  by_cases H : x ≠ 0 ∨ 0 ≤ m
  · exact (hasDerivAt_zpow m x H).deriv
  · rw [deriv_zero_of_not_differentiableAt (mt differentiableAt_zpow.1 H)]
    push_neg at H
    rcases H with ⟨rfl, hm⟩
    

Proof state:
case neg.intro
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : 𝕜
s : Set 𝕜
m✝ m : ℤ
hm : m < 0
⊢ 0 = ↑m * 0 ^ (m - 1)

Next tactic:
rw [zero_zpow _ ((sub_one_lt _).trans hm).ne, mul_zero]
@[simp]
theorem iter_deriv_zpow' (m : ℤ) (k : ℕ) :
    (deriv^[k] fun x : 𝕜 => x ^ m) =
      fun x => (∏ i in Finset.range k, ((m : 𝕜) - i)) * x ^ (m - k) := by
  

Proof state:
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : 𝕜
s : Set 𝕜
m✝ m : ℤ
k : ℕ
⊢ (deriv^[k] fun x => x ^ m) = fun x => (∏ i in Finset.range k, (↑m - ↑i)) * x ^ (m - ↑k)

Next tactic:
induction' k with k ihk
@[simp]
theorem iter_deriv_zpow' (m : ℤ) (k : ℕ) :
    (deriv^[k] fun x : 𝕜 => x ^ m) =
      fun x => (∏ i in Finset.range k, ((m : 𝕜) - i)) * x ^ (m - k) := by
  induction' k with k ihk
  · 

Proof state:
case zero
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : 𝕜
s : Set 𝕜
m✝ m : ℤ
⊢ (deriv^[Nat.zero] fun x => x ^ m) = fun x => (∏ i in Finset.range Nat.zero, (↑m - ↑i)) * x ^ (m - ↑Nat.zero)

Next tactic:
simp only [Nat.zero_eq, one_mul, Int.ofNat_zero, id, sub_zero, Finset.prod_range_zero,
      Function.iterate_zero]
@[simp]
theorem iter_deriv_zpow' (m : ℤ) (k : ℕ) :
    (deriv^[k] fun x : 𝕜 => x ^ m) =
      fun x => (∏ i in Finset.range k, ((m : 𝕜) - i)) * x ^ (m - k) := by
  induction' k with k ihk
  · simp only [Nat.zero_eq, one_mul, Int.ofNat_zero, id, sub_zero, Finset.prod_range_zero,
      Function.iterate_zero]
  · 

Proof state:
case succ
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : 𝕜
s : Set 𝕜
m✝ m : ℤ
k : ℕ
ihk : (deriv^[k] fun x => x ^ m) = fun x => (∏ i in Finset.range k, (↑m - ↑i)) * x ^ (m - ↑k)
⊢ (deriv^[Nat.succ k] fun x => x ^ m) = fun x => (∏ i in Finset.range (Nat.succ k), (↑m - ↑i)) * x ^ (m - ↑(Nat.succ k))

Next tactic:
simp only [Function.iterate_succ_apply', ihk, deriv_const_mul_field', deriv_zpow',
      Finset.prod_range_succ, Int.ofNat_succ, ← sub_sub, Int.cast_sub, Int.cast_ofNat, mul_assoc]
theorem iter_deriv_pow (n : ℕ) (x : 𝕜) (k : ℕ) :
    deriv^[k] (fun x : 𝕜 => x ^ n) x = (∏ i in Finset.range k, ((n : 𝕜) - i)) * x ^ (n - k) := by
  

Proof state:
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m : ℤ
n : ℕ
x : 𝕜
k : ℕ
⊢ deriv^[k] (fun x => x ^ n) x = (∏ i in Finset.range k, (↑n - ↑i)) * x ^ (n - k)

Next tactic:
simp only [← zpow_ofNat, iter_deriv_zpow, Int.cast_ofNat]
theorem iter_deriv_pow (n : ℕ) (x : 𝕜) (k : ℕ) :
    deriv^[k] (fun x : 𝕜 => x ^ n) x = (∏ i in Finset.range k, ((n : 𝕜) - i)) * x ^ (n - k) := by
  simp only [← zpow_ofNat, iter_deriv_zpow, Int.cast_ofNat]
  

Proof state:
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m : ℤ
n : ℕ
x : 𝕜
k : ℕ
⊢ (∏ x in Finset.range k, (↑n - ↑x)) * x ^ (↑n - ↑k) = (∏ i in Finset.range k, (↑n - ↑i)) * x ^ ↑(n - k)

Next tactic:
rcases le_or_lt k n with hkn | hnk
theorem iter_deriv_pow (n : ℕ) (x : 𝕜) (k : ℕ) :
    deriv^[k] (fun x : 𝕜 => x ^ n) x = (∏ i in Finset.range k, ((n : 𝕜) - i)) * x ^ (n - k) := by
  simp only [← zpow_ofNat, iter_deriv_zpow, Int.cast_ofNat]
  rcases le_or_lt k n with hkn | hnk
  · 

Proof state:
case inl
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m : ℤ
n : ℕ
x : 𝕜
k : ℕ
hkn : k ≤ n
⊢ (∏ x in Finset.range k, (↑n - ↑x)) * x ^ (↑n - ↑k) = (∏ i in Finset.range k, (↑n - ↑i)) * x ^ ↑(n - k)

Next tactic:
rw [Int.ofNat_sub hkn]
theorem iter_deriv_pow (n : ℕ) (x : 𝕜) (k : ℕ) :
    deriv^[k] (fun x : 𝕜 => x ^ n) x = (∏ i in Finset.range k, ((n : 𝕜) - i)) * x ^ (n - k) := by
  simp only [← zpow_ofNat, iter_deriv_zpow, Int.cast_ofNat]
  rcases le_or_lt k n with hkn | hnk
  · rw [Int.ofNat_sub hkn]
  · 

Proof state:
case inr
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m : ℤ
n : ℕ
x : 𝕜
k : ℕ
hnk : n < k
⊢ (∏ x in Finset.range k, (↑n - ↑x)) * x ^ (↑n - ↑k) = (∏ i in Finset.range k, (↑n - ↑i)) * x ^ ↑(n - k)

Next tactic:
have : (∏ i in Finset.range k, (n - i : 𝕜)) = 0 :=
      Finset.prod_eq_zero (Finset.mem_range.2 hnk) (sub_self _)
theorem iter_deriv_pow (n : ℕ) (x : 𝕜) (k : ℕ) :
    deriv^[k] (fun x : 𝕜 => x ^ n) x = (∏ i in Finset.range k, ((n : 𝕜) - i)) * x ^ (n - k) := by
  simp only [← zpow_ofNat, iter_deriv_zpow, Int.cast_ofNat]
  rcases le_or_lt k n with hkn | hnk
  · rw [Int.ofNat_sub hkn]
  · have : (∏ i in Finset.range k, (n - i : 𝕜)) = 0 :=
      Finset.prod_eq_zero (Finset.mem_range.2 hnk) (sub_self _)
    

Proof state:
case inr
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m : ℤ
n : ℕ
x : 𝕜
k : ℕ
hnk : n < k
this : ∏ i in Finset.range k, (↑n - ↑i) = 0
⊢ (∏ x in Finset.range k, (↑n - ↑x)) * x ^ (↑n - ↑k) = (∏ i in Finset.range k, (↑n - ↑i)) * x ^ ↑(n - k)

Next tactic:
simp only [this, zero_mul]
theorem iter_deriv_inv (k : ℕ) (x : 𝕜) :
    deriv^[k] Inv.inv x = (∏ i in Finset.range k, (-1 - i : 𝕜)) * x ^ (-1 - k : ℤ) := by
  

Proof state:
𝕜 : Type u
inst✝² : NontriviallyNormedField 𝕜
E : Type v
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x✝ : 𝕜
s : Set 𝕜
m : ℤ
k : ℕ
x : 𝕜
⊢ deriv^[k] Inv.inv x = (∏ i in Finset.range k, (-1 - ↑i)) * x ^ (-1 - ↑k)

Next tactic:
simpa only [zpow_neg_one, Int.cast_neg, Int.cast_one] using iter_deriv_zpow (-1) x k
/-- Auxiliary definition for `prodLift`. -/
noncomputable def prodLift₁ :
    W₁.Localization ⥤ C₂ ⥤ E :=
  Construction.lift (curry.obj F) (fun _ _ f₁ hf₁ => by
    

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
x✝¹ x✝ : C₁
f₁ : x✝¹ ⟶ x✝
hf₁ : W₁ f₁
⊢ IsIso ((curry.obj F).map f₁)

Next tactic:
haveI : ∀ (X₂ : C₂), IsIso (((curry.obj F).map f₁).app X₂) :=
      fun X₂ => hF _ ⟨hf₁, MorphismProperty.id_mem _ _⟩
/-- Auxiliary definition for `prodLift`. -/
noncomputable def prodLift₁ :
    W₁.Localization ⥤ C₂ ⥤ E :=
  Construction.lift (curry.obj F) (fun _ _ f₁ hf₁ => by
    haveI : ∀ (X₂ : C₂), IsIso (((curry.obj F).map f₁).app X₂) :=
      fun X₂ => hF _ ⟨hf₁, MorphismProperty.id_mem _ _⟩
    

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
x✝¹ x✝ : C₁
f₁ : x✝¹ ⟶ x✝
hf₁ : W₁ f₁
this : ∀ (X₂ : C₂), IsIso (((curry.obj F).map f₁).app X₂)
⊢ IsIso ((curry.obj F).map f₁)

Next tactic:
apply NatIso.isIso_of_isIso_app
/-- The lifting of a functor `F : C₁ × C₂ ⥤ E` inverting `W₁.prod W₂` to a functor
`W₁.Localization × W₂.Localization ⥤ E` -/
noncomputable def prodLift :
    W₁.Localization × W₂.Localization ⥤ E := by
  

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
⊢ MorphismProperty.Localization W₁ × MorphismProperty.Localization W₂ ⥤ E

Next tactic:
refine' uncurry.obj (Construction.lift (prodLift₁ F hF).flip _).flip
/-- The lifting of a functor `F : C₁ × C₂ ⥤ E` inverting `W₁.prod W₂` to a functor
`W₁.Localization × W₂.Localization ⥤ E` -/
noncomputable def prodLift :
    W₁.Localization × W₂.Localization ⥤ E := by
  refine' uncurry.obj (Construction.lift (prodLift₁ F hF).flip _).flip
  

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
⊢ MorphismProperty.IsInvertedBy W₂ (Functor.flip (prodLift₁ F hF))

Next tactic:
intro _ _ f₂ hf₂
/-- The lifting of a functor `F : C₁ × C₂ ⥤ E` inverting `W₁.prod W₂` to a functor
`W₁.Localization × W₂.Localization ⥤ E` -/
noncomputable def prodLift :
    W₁.Localization × W₂.Localization ⥤ E := by
  refine' uncurry.obj (Construction.lift (prodLift₁ F hF).flip _).flip
  intro _ _ f₂ hf₂
  

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
X✝ Y✝ : C₂
f₂ : X✝ ⟶ Y✝
hf₂ : W₂ f₂
⊢ IsIso ((Functor.flip (prodLift₁ F hF)).map f₂)

Next tactic:
haveI : ∀ (X₁ : W₁.Localization),
      IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app X₁) := fun X₁ => by
    obtain ⟨X₁, rfl⟩ := (Construction.objEquiv W₁).surjective X₁
    exact ((MorphismProperty.RespectsIso.isomorphisms E).arrow_mk_iso_iff
      (((Functor.mapArrowFunctor _ _).mapIso
        (eqToIso (Functor.congr_obj (prod_fac₁ F hF) X₁))).app (Arrow.mk f₂))).2
          (hF _ ⟨MorphismProperty.id_mem _ _, hf₂⟩)
/-- The lifting of a functor `F : C₁ × C₂ ⥤ E` inverting `W₁.prod W₂` to a functor
`W₁.Localization × W₂.Localization ⥤ E` -/
noncomputable def prodLift :
    W₁.Localization × W₂.Localization ⥤ E := by
  refine' uncurry.obj (Construction.lift (prodLift₁ F hF).flip _).flip
  intro _ _ f₂ hf₂
  haveI : ∀ (X₁ : W₁.Localization),
      IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app X₁) := fun X₁ => by
    

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
X✝ Y✝ : C₂
f₂ : X✝ ⟶ Y✝
hf₂ : W₂ f₂
X₁ : MorphismProperty.Localization W₁
⊢ IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app X₁)

Next tactic:
obtain ⟨X₁, rfl⟩ := (Construction.objEquiv W₁).surjective X₁
/-- The lifting of a functor `F : C₁ × C₂ ⥤ E` inverting `W₁.prod W₂` to a functor
`W₁.Localization × W₂.Localization ⥤ E` -/
noncomputable def prodLift :
    W₁.Localization × W₂.Localization ⥤ E := by
  refine' uncurry.obj (Construction.lift (prodLift₁ F hF).flip _).flip
  intro _ _ f₂ hf₂
  haveI : ∀ (X₁ : W₁.Localization),
      IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app X₁) := fun X₁ => by
    obtain ⟨X₁, rfl⟩ := (Construction.objEquiv W₁).surjective X₁
    

Proof state:
case intro
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
X✝ Y✝ : C₂
f₂ : X✝ ⟶ Y✝
hf₂ : W₂ f₂
X₁ : C₁
⊢ IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app ((Construction.objEquiv W₁) X₁))

Next tactic:
exact ((MorphismProperty.RespectsIso.isomorphisms E).arrow_mk_iso_iff
      (((Functor.mapArrowFunctor _ _).mapIso
        (eqToIso (Functor.congr_obj (prod_fac₁ F hF) X₁))).app (Arrow.mk f₂))).2
          (hF _ ⟨MorphismProperty.id_mem _ _, hf₂⟩)
/-- The lifting of a functor `F : C₁ × C₂ ⥤ E` inverting `W₁.prod W₂` to a functor
`W₁.Localization × W₂.Localization ⥤ E` -/
noncomputable def prodLift :
    W₁.Localization × W₂.Localization ⥤ E := by
  refine' uncurry.obj (Construction.lift (prodLift₁ F hF).flip _).flip
  intro _ _ f₂ hf₂
  haveI : ∀ (X₁ : W₁.Localization),
      IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app X₁) := fun X₁ => by
    obtain ⟨X₁, rfl⟩ := (Construction.objEquiv W₁).surjective X₁
    exact ((MorphismProperty.RespectsIso.isomorphisms E).arrow_mk_iso_iff
      (((Functor.mapArrowFunctor _ _).mapIso
        (eqToIso (Functor.congr_obj (prod_fac₁ F hF) X₁))).app (Arrow.mk f₂))).2
          (hF _ ⟨MorphismProperty.id_mem _ _, hf₂⟩)
  

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
X✝ Y✝ : C₂
f₂ : X✝ ⟶ Y✝
hf₂ : W₂ f₂
this : ∀ (X₁ : MorphismProperty.Localization W₁), IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app X₁)
⊢ IsIso ((Functor.flip (prodLift₁ F hF)).map f₂)

Next tactic:
apply NatIso.isIso_of_isIso_app
lemma prod_fac₂ :
    W₂.Q ⋙ (curry.obj (prodLift F hF)).flip = (prodLift₁ F hF).flip := by
  

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
⊢ MorphismProperty.Q W₂ ⋙ Functor.flip (curry.obj (prodLift F hF)) = Functor.flip (prodLift₁ F hF)

Next tactic:
simp only [prodLift, Functor.curry_obj_uncurry_obj, Functor.flip_flip]
lemma prod_fac₂ :
    W₂.Q ⋙ (curry.obj (prodLift F hF)).flip = (prodLift₁ F hF).flip := by
  simp only [prodLift, Functor.curry_obj_uncurry_obj, Functor.flip_flip]
  

Proof state:
C₁ : Type u₁
C₂ : Type u₂
D₁ : Type u₃
D₂ : Type u₄
inst✝⁶ : Category.{v₁, u₁} C₁
inst✝⁵ : Category.{v₂, u₂} C₂
inst✝⁴ : Category.{v₃, u₃} D₁
inst✝³ : Category.{v₄, u₄} D₂
L₁ : C₁ ⥤ D₁
W₁ : MorphismProperty C₁
inst✝² : MorphismProperty.ContainsIdentities W₁
L₂ : C₂ ⥤ D₂
W₂ : MorphismProperty C₂
inst✝¹ : MorphismProperty.ContainsIdentities W₂
E : Type u₅
inst✝ : Category.{v₅, u₅} E
F : C₁ × C₂ ⥤ E
hF : MorphismProperty.IsInvertedBy (MorphismProperty.prod W₁ W₂) F
⊢ MorphismProperty.Q W₂ ⋙
      Construction.lift (Functor.flip (prodLift₁ F hF))
        (_ : ∀ ⦃X Y : C₂⦄ (f₂ : X ⟶ Y), W₂ f₂ → IsIso ((Functor.flip (prodLift₁ F hF)).map f₂)) =
    Functor.flip (prodLift₁ F hF)

Next tactic:
apply Construction.fac