l3lab/ntp-mathlib huggingface dataset:
/-- The composition of an updated function with an equiv on a subtype can be expressed as an
updated function. -/
-- porting note: replace `s : Set α` and `: s` with `p : α → Prop` and `: Subtype p`, since the
-- former now unfolds syntactically to a less general case of the latter.
theorem dite_comp_equiv_update {α : Type*} {β : Sort*} {γ : Sort*} {p : α → Prop}
    (e : β ≃ Subtype p)
    (v : β → γ) (w : α → γ) (j : β) (x : γ) [DecidableEq β] [DecidableEq α]
    [∀ j, Decidable (p j)] :
    (fun i : α => if h : p i then (Function.update v j x) (e.symm ⟨i, h⟩) else w i) =
      Function.update (fun i : α => if h : p i then v (e.symm ⟨i, h⟩) else w i) (e j) x := by
  ext i
  by_cases h : p i
  · rw [dif_pos h, Function.update_apply_equiv_apply, Equiv.symm_symm,
      Function.update_apply, Function.update_apply, dif_pos h]
    have h_coe : (⟨i, h⟩ : Subtype p) = e j ↔ i = e j :=
      Subtype.ext_iff.trans (by rw [Subtype.coe_mk])
    

Proof state:
case pos
α✝ : Sort u
β✝ : Sort v
γ✝ : Sort w
α : Type u_1
β : Sort u_2
γ : Sort u_3
p : α → Prop
e : β ≃ Subtype p
v : β → γ
w : α → γ
j : β
x : γ
inst✝² : DecidableEq β
inst✝¹ : DecidableEq α
inst✝ : (j : α) → Decidable (p j)
i : α
h : p i
h_coe : { val := i, property := h } = e j ↔ i = ↑(e j)
⊢ (if { val := i, property := h } = e j then x else (v ∘ ⇑e.symm) { val := i, property := h }) =
    if i = ↑(e j) then x else v (e.symm { val := i, property := h })

Next tactic:
simp [h_coe]
/-- The composition of an updated function with an equiv on a subtype can be expressed as an
updated function. -/
-- porting note: replace `s : Set α` and `: s` with `p : α → Prop` and `: Subtype p`, since the
-- former now unfolds syntactically to a less general case of the latter.
theorem dite_comp_equiv_update {α : Type*} {β : Sort*} {γ : Sort*} {p : α → Prop}
    (e : β ≃ Subtype p)
    (v : β → γ) (w : α → γ) (j : β) (x : γ) [DecidableEq β] [DecidableEq α]
    [∀ j, Decidable (p j)] :
    (fun i : α => if h : p i then (Function.update v j x) (e.symm ⟨i, h⟩) else w i) =
      Function.update (fun i : α => if h : p i then v (e.symm ⟨i, h⟩) else w i) (e j) x := by
  ext i
  by_cases h : p i
  · rw [dif_pos h, Function.update_apply_equiv_apply, Equiv.symm_symm,
      Function.update_apply, Function.update_apply, dif_pos h]
    have h_coe : (⟨i, h⟩ : Subtype p) = e j ↔ i = e j :=
      Subtype.ext_iff.trans (by rw [Subtype.coe_mk])
    simp [h_coe]
  · 

Proof state:
case neg
α✝ : Sort u
β✝ : Sort v
γ✝ : Sort w
α : Type u_1
β : Sort u_2
γ : Sort u_3
p : α → Prop
e : β ≃ Subtype p
v : β → γ
w : α → γ
j : β
x : γ
inst✝² : DecidableEq β
inst✝¹ : DecidableEq α
inst✝ : (j : α) → Decidable (p j)
i : α
h : ¬p i
⊢ (if h : p i then update v j x (e.symm { val := i, property := h }) else w i) =
    update (fun i => if h : p i then v (e.symm { val := i, property := h }) else w i) (↑(e j)) x i

Next tactic:
have : i ≠ e j := by
      contrapose! h
      have : p (e j : α) := (e j).2
      rwa [← h] at this
/-- The composition of an updated function with an equiv on a subtype can be expressed as an
updated function. -/
-- porting note: replace `s : Set α` and `: s` with `p : α → Prop` and `: Subtype p`, since the
-- former now unfolds syntactically to a less general case of the latter.
theorem dite_comp_equiv_update {α : Type*} {β : Sort*} {γ : Sort*} {p : α → Prop}
    (e : β ≃ Subtype p)
    (v : β → γ) (w : α → γ) (j : β) (x : γ) [DecidableEq β] [DecidableEq α]
    [∀ j, Decidable (p j)] :
    (fun i : α => if h : p i then (Function.update v j x) (e.symm ⟨i, h⟩) else w i) =
      Function.update (fun i : α => if h : p i then v (e.symm ⟨i, h⟩) else w i) (e j) x := by
  ext i
  by_cases h : p i
  · rw [dif_pos h, Function.update_apply_equiv_apply, Equiv.symm_symm,
      Function.update_apply, Function.update_apply, dif_pos h]
    have h_coe : (⟨i, h⟩ : Subtype p) = e j ↔ i = e j :=
      Subtype.ext_iff.trans (by rw [Subtype.coe_mk])
    simp [h_coe]
  · have : i ≠ e j := by
      

Proof state:
α✝ : Sort u
β✝ : Sort v
γ✝ : Sort w
α : Type u_1
β : Sort u_2
γ : Sort u_3
p : α → Prop
e : β ≃ Subtype p
v : β → γ
w : α → γ
j : β
x : γ
inst✝² : DecidableEq β
inst✝¹ : DecidableEq α
inst✝ : (j : α) → Decidable (p j)
i : α
h : ¬p i
⊢ i ≠ ↑(e j)

Next tactic:
contrapose! h
/-- The composition of an updated function with an equiv on a subtype can be expressed as an
updated function. -/
-- porting note: replace `s : Set α` and `: s` with `p : α → Prop` and `: Subtype p`, since the
-- former now unfolds syntactically to a less general case of the latter.
theorem dite_comp_equiv_update {α : Type*} {β : Sort*} {γ : Sort*} {p : α → Prop}
    (e : β ≃ Subtype p)
    (v : β → γ) (w : α → γ) (j : β) (x : γ) [DecidableEq β] [DecidableEq α]
    [∀ j, Decidable (p j)] :
    (fun i : α => if h : p i then (Function.update v j x) (e.symm ⟨i, h⟩) else w i) =
      Function.update (fun i : α => if h : p i then v (e.symm ⟨i, h⟩) else w i) (e j) x := by
  ext i
  by_cases h : p i
  · rw [dif_pos h, Function.update_apply_equiv_apply, Equiv.symm_symm,
      Function.update_apply, Function.update_apply, dif_pos h]
    have h_coe : (⟨i, h⟩ : Subtype p) = e j ↔ i = e j :=
      Subtype.ext_iff.trans (by rw [Subtype.coe_mk])
    simp [h_coe]
  · have : i ≠ e j := by
      contrapose! h
      

Proof state:
α✝ : Sort u
β✝ : Sort v
γ✝ : Sort w
α : Type u_1
β : Sort u_2
γ : Sort u_3
p : α → Prop
e : β ≃ Subtype p
v : β → γ
w : α → γ
j : β
x : γ
inst✝² : DecidableEq β
inst✝¹ : DecidableEq α
inst✝ : (j : α) → Decidable (p j)
i : α
h : i = ↑(e j)
⊢ p i

Next tactic:
have : p (e j : α) := (e j).2
/-- The composition of an updated function with an equiv on a subtype can be expressed as an
updated function. -/
-- porting note: replace `s : Set α` and `: s` with `p : α → Prop` and `: Subtype p`, since the
-- former now unfolds syntactically to a less general case of the latter.
theorem dite_comp_equiv_update {α : Type*} {β : Sort*} {γ : Sort*} {p : α → Prop}
    (e : β ≃ Subtype p)
    (v : β → γ) (w : α → γ) (j : β) (x : γ) [DecidableEq β] [DecidableEq α]
    [∀ j, Decidable (p j)] :
    (fun i : α => if h : p i then (Function.update v j x) (e.symm ⟨i, h⟩) else w i) =
      Function.update (fun i : α => if h : p i then v (e.symm ⟨i, h⟩) else w i) (e j) x := by
  ext i
  by_cases h : p i
  · rw [dif_pos h, Function.update_apply_equiv_apply, Equiv.symm_symm,
      Function.update_apply, Function.update_apply, dif_pos h]
    have h_coe : (⟨i, h⟩ : Subtype p) = e j ↔ i = e j :=
      Subtype.ext_iff.trans (by rw [Subtype.coe_mk])
    simp [h_coe]
  · have : i ≠ e j := by
      contrapose! h
      have : p (e j : α) := (e j).2
      

Proof state:
α✝ : Sort u
β✝ : Sort v
γ✝ : Sort w
α : Type u_1
β : Sort u_2
γ : Sort u_3
p : α → Prop
e : β ≃ Subtype p
v : β → γ
w : α → γ
j : β
x : γ
inst✝² : DecidableEq β
inst✝¹ : DecidableEq α
inst✝ : (j : α) → Decidable (p j)
i : α
h : i = ↑(e j)
this : p ↑(e j)
⊢ p i

Next tactic:
rwa [← h] at this
/-- The composition of an updated function with an equiv on a subtype can be expressed as an
updated function. -/
-- porting note: replace `s : Set α` and `: s` with `p : α → Prop` and `: Subtype p`, since the
-- former now unfolds syntactically to a less general case of the latter.
theorem dite_comp_equiv_update {α : Type*} {β : Sort*} {γ : Sort*} {p : α → Prop}
    (e : β ≃ Subtype p)
    (v : β → γ) (w : α → γ) (j : β) (x : γ) [DecidableEq β] [DecidableEq α]
    [∀ j, Decidable (p j)] :
    (fun i : α => if h : p i then (Function.update v j x) (e.symm ⟨i, h⟩) else w i) =
      Function.update (fun i : α => if h : p i then v (e.symm ⟨i, h⟩) else w i) (e j) x := by
  ext i
  by_cases h : p i
  · rw [dif_pos h, Function.update_apply_equiv_apply, Equiv.symm_symm,
      Function.update_apply, Function.update_apply, dif_pos h]
    have h_coe : (⟨i, h⟩ : Subtype p) = e j ↔ i = e j :=
      Subtype.ext_iff.trans (by rw [Subtype.coe_mk])
    simp [h_coe]
  · have : i ≠ e j := by
      contrapose! h
      have : p (e j : α) := (e j).2
      rwa [← h] at this
    

Proof state:
case neg
α✝ : Sort u
β✝ : Sort v
γ✝ : Sort w
α : Type u_1
β : Sort u_2
γ : Sort u_3
p : α → Prop
e : β ≃ Subtype p
v : β → γ
w : α → γ
j : β
x : γ
inst✝² : DecidableEq β
inst✝¹ : DecidableEq α
inst✝ : (j : α) → Decidable (p j)
i : α
h : ¬p i
this : i ≠ ↑(e j)
⊢ (if h : p i then update v j x (e.symm { val := i, property := h }) else w i) =
    update (fun i => if h : p i then v (e.symm { val := i, property := h }) else w i) (↑(e j)) x i

Next tactic:
simp [h, this]
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  

Proof state:
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
⊢ HasFDerivAt (Function.update x i) (ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))) y

Next tactic:
set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  

Proof state:
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
⊢ HasFDerivAt (Function.update x i) l y

Next tactic:
have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · 

Proof state:
case update_eq
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
⊢ Function.update x i = (fun x_1 => x) + ⇑l ∘ fun x_1 => x_1 - x i

Next tactic:
ext t j
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    

Proof state:
case update_eq.h.h
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
t : E i
j : ι
⊢ Function.update x i t j = ((fun x_1 => x) + ⇑l ∘ fun x_1 => x_1 - x i) t j

Next tactic:
dsimp [Pi.single, Function.update]
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    dsimp [Pi.single, Function.update]
    

Proof state:
case update_eq.h.h
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
t : E i
j : ι
⊢ (if h : j = i then (_ : i = j) ▸ t else x j) =
    x j + (if h : j = i then (_ : i = j) ▸ ContinuousLinearMap.id 𝕜 (E i) else 0) (t - x i)

Next tactic:
split_ifs with hji
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    dsimp [Pi.single, Function.update]
    split_ifs with hji
    · 

Proof state:
case pos
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
t : E i
j : ι
hji : j = i
⊢ (_ : i = j) ▸ t = x j + ((_ : i = j) ▸ ContinuousLinearMap.id 𝕜 (E i)) (t - x i)

Next tactic:
subst hji
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    dsimp [Pi.single, Function.update]
    split_ifs with hji
    · subst hji
      

Proof state:
case pos
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
j : ι
y : E j
l : E j →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single j (ContinuousLinearMap.id 𝕜 (E j)))
t : E j
⊢ (_ : j = j) ▸ t = x j + ((_ : j = j) ▸ ContinuousLinearMap.id 𝕜 (E j)) (t - x j)

Next tactic:
simp
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    dsimp [Pi.single, Function.update]
    split_ifs with hji
    · subst hji
      simp
    · 

Proof state:
case neg
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
t : E i
j : ι
hji : ¬j = i
⊢ x j = x j + 0 (t - x i)

Next tactic:
simp
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    dsimp [Pi.single, Function.update]
    split_ifs with hji
    · subst hji
      simp
    · simp
  

Proof state:
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
update_eq : Function.update x i = (fun x_1 => x) + ⇑l ∘ fun x_1 => x_1 - x i
⊢ HasFDerivAt (Function.update x i) l y

Next tactic:
rw [update_eq]
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    dsimp [Pi.single, Function.update]
    split_ifs with hji
    · subst hji
      simp
    · simp
  rw [update_eq]
  

Proof state:
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
update_eq : Function.update x i = (fun x_1 => x) + ⇑l ∘ fun x_1 => x_1 - x i
⊢ HasFDerivAt ((fun x_1 => x) + ⇑l ∘ fun x_1 => x_1 - x i) l y

Next tactic:
convert (hasFDerivAt_const _ _).add (l.hasFDerivAt.comp y (hasFDerivAt_sub_const (x i)))
theorem hasFDerivAt_update (x : ∀ i, E i) {i : ι} (y : E i) :
    HasFDerivAt (Function.update x i) (.pi (Pi.single i (.id 𝕜 (E i)))) y := by
  set l := (ContinuousLinearMap.pi (Pi.single i (.id 𝕜 (E i))))
  have update_eq : Function.update x i = (fun _ ↦ x) + l ∘ (· - x i)
  · ext t j
    dsimp [Pi.single, Function.update]
    split_ifs with hji
    · subst hji
      simp
    · simp
  rw [update_eq]
  convert (hasFDerivAt_const _ _).add (l.hasFDerivAt.comp y (hasFDerivAt_sub_const (x i)))
  

Proof state:
case h.e'_10
𝕜 : Type u_1
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Fintype ι
inst✝⁴ : NontriviallyNormedField 𝕜
E : ι → Type u_3
inst✝³ : (i : ι) → NormedAddCommGroup (E i)
inst✝² : (i : ι) → NormedSpace 𝕜 (E i)
F : Type u_4
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : (i : ι) → E i
i : ι
y : E i
l : E i →L[𝕜] (i : ι) → E i := ContinuousLinearMap.pi (Pi.single i (ContinuousLinearMap.id 𝕜 (E i)))
update_eq : Function.update x i = (fun x_1 => x) + ⇑l ∘ fun x_1 => x_1 - x i
⊢ l = 0 + ContinuousLinearMap.comp l (ContinuousLinearMap.id 𝕜 (E i))

Next tactic:
rw [zero_add, ContinuousLinearMap.comp_id]
@[reassoc (attr := simp)]
lemma map_comp_map_s (φ : W.LeftFraction X Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    φ.map L hL ≫ L.map φ.s = L.map φ.f := by
  

Proof state:
C : Type u_1
D : Type u_4
inst✝¹ : Category.{u_2, u_1} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
φ : LeftFraction W X Y
L : C ⥤ D
hL : IsInvertedBy W L
⊢ map φ L hL ≫ L.map φ.s = L.map φ.f

Next tactic:
letI := hL _ φ.hs
@[reassoc (attr := simp)]
lemma map_comp_map_s (φ : W.LeftFraction X Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    φ.map L hL ≫ L.map φ.s = L.map φ.f := by
  letI := hL _ φ.hs
  

Proof state:
C : Type u_1
D : Type u_4
inst✝¹ : Category.{u_2, u_1} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
φ : LeftFraction W X Y
L : C ⥤ D
hL : IsInvertedBy W L
this : IsIso (L.map φ.s) := hL φ.s φ.hs
⊢ map φ L hL ≫ L.map φ.s = L.map φ.f

Next tactic:
simp [map]
lemma map_ofHom (f : X ⟶ Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) [W.ContainsIdentities] :
    (ofHom W f).map L hL = L.map f := by
  

Proof state:
C : Type u_2
D : Type u_4
inst✝² : Category.{u_1, u_2} C
inst✝¹ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
f : X ⟶ Y
L : C ⥤ D
hL : IsInvertedBy W L
inst✝ : ContainsIdentities W
⊢ map (ofHom W f) L hL = L.map f

Next tactic:
simp [map]
@[reassoc (attr := simp)]
lemma map_ofInv_hom_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    (ofInv s hs).map L hL ≫ L.map s = 𝟙 _ := by
  

Proof state:
C : Type u_2
D : Type u_4
inst✝¹ : Category.{u_1, u_2} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
s : Y ⟶ X
hs : W s
L : C ⥤ D
hL : IsInvertedBy W L
⊢ map (ofInv s hs) L hL ≫ L.map s = 𝟙 (L.obj X)

Next tactic:
letI := hL _ hs
@[reassoc (attr := simp)]
lemma map_ofInv_hom_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    (ofInv s hs).map L hL ≫ L.map s = 𝟙 _ := by
  letI := hL _ hs
  

Proof state:
C : Type u_2
D : Type u_4
inst✝¹ : Category.{u_1, u_2} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
s : Y ⟶ X
hs : W s
L : C ⥤ D
hL : IsInvertedBy W L
this : IsIso (L.map s) := hL s hs
⊢ map (ofInv s hs) L hL ≫ L.map s = 𝟙 (L.obj X)

Next tactic:
simp [map]
@[reassoc (attr := simp)]
lemma map_hom_ofInv_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    L.map s ≫ (ofInv s hs).map L hL = 𝟙 _ := by
  

Proof state:
C : Type u_2
D : Type u_4
inst✝¹ : Category.{u_1, u_2} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
s : Y ⟶ X
hs : W s
L : C ⥤ D
hL : IsInvertedBy W L
⊢ L.map s ≫ map (ofInv s hs) L hL = 𝟙 (L.obj Y)

Next tactic:
letI := hL _ hs
@[reassoc (attr := simp)]
lemma map_hom_ofInv_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    L.map s ≫ (ofInv s hs).map L hL = 𝟙 _ := by
  letI := hL _ hs
  

Proof state:
C : Type u_2
D : Type u_4
inst✝¹ : Category.{u_1, u_2} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
s : Y ⟶ X
hs : W s
L : C ⥤ D
hL : IsInvertedBy W L
this : IsIso (L.map s) := hL s hs
⊢ L.map s ≫ map (ofInv s hs) L hL = 𝟙 (L.obj Y)

Next tactic:
simp [map]
@[reassoc (attr := simp)]
lemma map_s_comp_map (φ : W.RightFraction X Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    L.map φ.s ≫ φ.map L hL = L.map φ.f := by
  

Proof state:
C : Type u_1
D : Type u_4
inst✝¹ : Category.{u_2, u_1} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
φ : RightFraction W X Y
L : C ⥤ D
hL : IsInvertedBy W L
⊢ L.map φ.s ≫ map φ L hL = L.map φ.f

Next tactic:
letI := hL _ φ.hs
@[reassoc (attr := simp)]
lemma map_s_comp_map (φ : W.RightFraction X Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) :
    L.map φ.s ≫ φ.map L hL = L.map φ.f := by
  letI := hL _ φ.hs
  

Proof state:
C : Type u_1
D : Type u_4
inst✝¹ : Category.{u_2, u_1} C
inst✝ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
φ : RightFraction W X Y
L : C ⥤ D
hL : IsInvertedBy W L
this : IsIso (L.map φ.s) := hL φ.s φ.hs
⊢ L.map φ.s ≫ map φ L hL = L.map φ.f

Next tactic:
simp [map]
@[simp]
lemma map_ofHom (f : X ⟶ Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) [W.ContainsIdentities] :
    (ofHom W f).map L hL = L.map f := by
  

Proof state:
C : Type u_2
D : Type u_4
inst✝² : Category.{u_1, u_2} C
inst✝¹ : Category.{u_3, u_4} D
W : MorphismProperty C
X Y : C
f : X ⟶ Y
L : C ⥤ D
hL : IsInvertedBy W L
inst✝ : ContainsIdentities W
⊢ map (ofHom W f) L hL = L.map f

Next tactic:
simp [map]
lemma refl {X Y : C} (z : W.LeftFraction X Y) : LeftFractionRel z z :=
  ⟨z.Y', 𝟙 _, 𝟙 _, rfl, rfl, by 

Proof state:
C : Type u_1
D : Type ?u.30678
inst✝¹ : Category.{u_2, u_1} C
inst✝ : Category.{?u.30686, ?u.30678} D
W : MorphismProperty C
X Y : C
z : LeftFraction W X Y
⊢ W (z.s ≫ 𝟙 z.Y')

Next tactic:
simpa only [Category.comp_id] using z.hs
lemma symm {X Y : C} {z₁ z₂ : W.LeftFraction X Y} (h : LeftFractionRel z₁ z₂) :
    LeftFractionRel z₂ z₁ := by
  

Proof state:
C : Type u_1
D : Type ?u.31195
inst✝¹ : Category.{u_2, u_1} C
inst✝ : Category.{?u.31203, ?u.31195} D
W : MorphismProperty C
X Y : C
z₁ z₂ : LeftFraction W X Y
h : LeftFractionRel z₁ z₂
⊢ LeftFractionRel z₂ z₁

Next tactic:
obtain ⟨Z, t₁, t₂, hst, hft, ht⟩ := h
lemma symm {X Y : C} {z₁ z₂ : W.LeftFraction X Y} (h : LeftFractionRel z₁ z₂) :
    LeftFractionRel z₂ z₁ := by
  obtain ⟨Z, t₁, t₂, hst, hft, ht⟩ := h
  

Proof state:
case intro.intro.intro.intro.intro
C : Type u_1
D : Type ?u.31195
inst✝¹ : Category.{u_2, u_1} C
inst✝ : Category.{?u.31203, ?u.31195} D
W : MorphismProperty C
X Y : C
z₁ z₂ : LeftFraction W X Y
Z : C
t₁ : z₁.Y' ⟶ Z
t₂ : z₂.Y' ⟶ Z
hst : z₁.s ≫ t₁ = z₂.s ≫ t₂
hft : z₁.f ≫ t₁ = z₂.f ≫ t₂
ht : W (z₁.s ≫ t₁)
⊢ LeftFractionRel z₂ z₁

Next tactic:
exact ⟨Z, t₂, t₁, hst.symm, hft.symm, by simpa only [← hst] using ht⟩