l3lab/ntp-mathlib huggingface dataset:
/-- Corollary of the **Hahn-Banach theorem**: if `f : p → F` is a continuous linear map
from a submodule of a normed space `E` over `𝕜`, `𝕜 = ℝ` or `𝕜 = ℂ`,
with a finite dimensional range,
then `f` admits an extension to a continuous linear map `E → F`.

Note that contrary to the case `F = 𝕜`, see `exists_extension_norm_eq`,
we provide no estimates on the norm of the extension.
-/
lemma ContinuousLinearMap.exist_extension_of_finiteDimensional_range {p : Submodule 𝕜 E}
    (f : p →L[𝕜] F) [FiniteDimensional 𝕜 (LinearMap.range f)] :
    ∃ g : E →L[𝕜] F, f = g.comp p.subtypeL := by
  set b := finBasis 𝕜 (LinearMap.range f)
  set e := b.equivFunL
  set fi := fun i ↦ (LinearMap.toContinuousLinearMap (b.coord i)).comp
    (f.codRestrict _ <| LinearMap.mem_range_self _)
  choose gi hgf _ using fun i ↦ exists_extension_norm_eq p (fi i)
  use (LinearMap.range f).subtypeL.comp <| e.symm.toContinuousLinearMap.comp (.pi gi)
  

Proof state:
case h
𝕜 : Type u_1
inst✝⁵ : IsROrC 𝕜
E : Type u_2
F : Type u_3
inst✝⁴ : SeminormedAddCommGroup E
inst✝³ : NormedSpace 𝕜 E
inst✝² : NormedAddCommGroup F
inst✝¹ : NormedSpace 𝕜 F
p : Submodule 𝕜 E
f : ↥p →L[𝕜] F
inst✝ : FiniteDimensional 𝕜 ↥(LinearMap.range f)
b : Basis (Fin (finrank 𝕜 ↥(LinearMap.range f))) 𝕜 ↥(LinearMap.range f) := finBasis 𝕜 ↥(LinearMap.range f)
e : ↥(LinearMap.range f) ≃L[𝕜] Fin (finrank 𝕜 ↥(LinearMap.range f)) → 𝕜 := Basis.equivFunL b
fi : Fin (finrank 𝕜 ↥(LinearMap.range f)) → ↥p →L[𝕜] 𝕜 :=
  fun i =>
    comp (LinearMap.toContinuousLinearMap (Basis.coord b i))
      (codRestrict f (LinearMap.range f) (_ : ∀ (x : ↥p), f x ∈ LinearMap.range f))
gi : Fin (finrank 𝕜 ↥(LinearMap.range f)) → E →L[𝕜] 𝕜
hgf : ∀ (i : Fin (finrank 𝕜 ↥(LinearMap.range f))) (x : ↥p), (gi i) ↑x = (fi i) x
✝ : ∀ (i : Fin (finrank 𝕜 ↥(LinearMap.range f))), ‖gi i‖ = ‖fi i‖
⊢ f =
    comp (comp (Submodule.subtypeL (LinearMap.range f)) (comp (↑(ContinuousLinearEquiv.symm e)) (pi gi)))
      (Submodule.subtypeL p)

Next tactic:
ext x
/-- Corollary of the **Hahn-Banach theorem**: if `f : p → F` is a continuous linear map
from a submodule of a normed space `E` over `𝕜`, `𝕜 = ℝ` or `𝕜 = ℂ`,
with a finite dimensional range,
then `f` admits an extension to a continuous linear map `E → F`.

Note that contrary to the case `F = 𝕜`, see `exists_extension_norm_eq`,
we provide no estimates on the norm of the extension.
-/
lemma ContinuousLinearMap.exist_extension_of_finiteDimensional_range {p : Submodule 𝕜 E}
    (f : p →L[𝕜] F) [FiniteDimensional 𝕜 (LinearMap.range f)] :
    ∃ g : E →L[𝕜] F, f = g.comp p.subtypeL := by
  set b := finBasis 𝕜 (LinearMap.range f)
  set e := b.equivFunL
  set fi := fun i ↦ (LinearMap.toContinuousLinearMap (b.coord i)).comp
    (f.codRestrict _ <| LinearMap.mem_range_self _)
  choose gi hgf _ using fun i ↦ exists_extension_norm_eq p (fi i)
  use (LinearMap.range f).subtypeL.comp <| e.symm.toContinuousLinearMap.comp (.pi gi)
  ext x
  

Proof state:
case h.h
𝕜 : Type u_1
inst✝⁵ : IsROrC 𝕜
E : Type u_2
F : Type u_3
inst✝⁴ : SeminormedAddCommGroup E
inst✝³ : NormedSpace 𝕜 E
inst✝² : NormedAddCommGroup F
inst✝¹ : NormedSpace 𝕜 F
p : Submodule 𝕜 E
f : ↥p →L[𝕜] F
inst✝ : FiniteDimensional 𝕜 ↥(LinearMap.range f)
b : Basis (Fin (finrank 𝕜 ↥(LinearMap.range f))) 𝕜 ↥(LinearMap.range f) := finBasis 𝕜 ↥(LinearMap.range f)
e : ↥(LinearMap.range f) ≃L[𝕜] Fin (finrank 𝕜 ↥(LinearMap.range f)) → 𝕜 := Basis.equivFunL b
fi : Fin (finrank 𝕜 ↥(LinearMap.range f)) → ↥p →L[𝕜] 𝕜 :=
  fun i =>
    comp (LinearMap.toContinuousLinearMap (Basis.coord b i))
      (codRestrict f (LinearMap.range f) (_ : ∀ (x : ↥p), f x ∈ LinearMap.range f))
gi : Fin (finrank 𝕜 ↥(LinearMap.range f)) → E →L[𝕜] 𝕜
hgf : ∀ (i : Fin (finrank 𝕜 ↥(LinearMap.range f))) (x : ↥p), (gi i) ↑x = (fi i) x
✝ : ∀ (i : Fin (finrank 𝕜 ↥(LinearMap.range f))), ‖gi i‖ = ‖fi i‖
x : ↥p
⊢ f x =
    (comp (comp (Submodule.subtypeL (LinearMap.range f)) (comp (↑(ContinuousLinearEquiv.symm e)) (pi gi)))
        (Submodule.subtypeL p))
      x

Next tactic:
simp [hgf]
theorem coord_norm' {x : E} (h : x ≠ 0) : ‖(‖x‖ : 𝕜) • coord 𝕜 x h‖ = 1 := by
  

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
⊢ ‖↑‖x‖ • coord 𝕜 x h‖ = 1

Next tactic:
rw [norm_smul (x := coord 𝕜 x h), IsROrC.norm_coe_norm, coord_norm,
    mul_inv_cancel (mt norm_eq_zero.mp h)]
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
let p : Submodule 𝕜 E := 𝕜 ∙ x
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
let f := (‖x‖ : 𝕜) • coord 𝕜 x h
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  let f := (‖x‖ : 𝕜) • coord 𝕜 x h
  

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
f : ↥(span 𝕜 {x}) →L[𝕜] 𝕜 := ↑‖x‖ • coord 𝕜 x h
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
obtain ⟨g, hg⟩ := exists_extension_norm_eq p f
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  let f := (‖x‖ : 𝕜) • coord 𝕜 x h
  obtain ⟨g, hg⟩ := exists_extension_norm_eq p f
  

Proof state:
case intro
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
f : ↥(span 𝕜 {x}) →L[𝕜] 𝕜 := ↑‖x‖ • coord 𝕜 x h
g : E →L[𝕜] 𝕜
hg : (∀ (x : ↥p), g ↑x = f x) ∧ ‖g‖ = ‖f‖
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
refine' ⟨g, _, _⟩
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  let f := (‖x‖ : 𝕜) • coord 𝕜 x h
  obtain ⟨g, hg⟩ := exists_extension_norm_eq p f
  refine' ⟨g, _, _⟩
  · 

Proof state:
case intro.refine'_1
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
f : ↥(span 𝕜 {x}) →L[𝕜] 𝕜 := ↑‖x‖ • coord 𝕜 x h
g : E →L[𝕜] 𝕜
hg : (∀ (x : ↥p), g ↑x = f x) ∧ ‖g‖ = ‖f‖
⊢ ‖g‖ = 1

Next tactic:
rw [hg.2, coord_norm']
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  let f := (‖x‖ : 𝕜) • coord 𝕜 x h
  obtain ⟨g, hg⟩ := exists_extension_norm_eq p f
  refine' ⟨g, _, _⟩
  · rw [hg.2, coord_norm']
  · 

Proof state:
case intro.refine'_2
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
f : ↥(span 𝕜 {x}) →L[𝕜] 𝕜 := ↑‖x‖ • coord 𝕜 x h
g : E →L[𝕜] 𝕜
hg : (∀ (x : ↥p), g ↑x = f x) ∧ ‖g‖ = ‖f‖
⊢ g x = ↑‖x‖

Next tactic:
calc
      g x = g (⟨x, mem_span_singleton_self x⟩ : 𝕜 ∙ x) := by rw [coe_mk]
      _ = ((‖x‖ : 𝕜) • coord 𝕜 x h) (⟨x, mem_span_singleton_self x⟩ : 𝕜 ∙ x) := by rw [← hg.1]
      _ = ‖x‖ := by simp
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  let f := (‖x‖ : 𝕜) • coord 𝕜 x h
  obtain ⟨g, hg⟩ := exists_extension_norm_eq p f
  refine' ⟨g, _, _⟩
  · rw [hg.2, coord_norm']
  · calc
      g x = g (⟨x, mem_span_singleton_self x⟩ : 𝕜 ∙ x) := by 

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
f : ↥(span 𝕜 {x}) →L[𝕜] 𝕜 := ↑‖x‖ • coord 𝕜 x h
g : E →L[𝕜] 𝕜
hg : (∀ (x : ↥p), g ↑x = f x) ∧ ‖g‖ = ‖f‖
⊢ g x = g ↑{ val := x, property := (_ : x ∈ span 𝕜 {x}) }

Next tactic:
rw [coe_mk]
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  let f := (‖x‖ : 𝕜) • coord 𝕜 x h
  obtain ⟨g, hg⟩ := exists_extension_norm_eq p f
  refine' ⟨g, _, _⟩
  · rw [hg.2, coord_norm']
  · calc
      g x = g (⟨x, mem_span_singleton_self x⟩ : 𝕜 ∙ x) := by rw [coe_mk]
      _ = ((‖x‖ : 𝕜) • coord 𝕜 x h) (⟨x, mem_span_singleton_self x⟩ : 𝕜 ∙ x) := by 

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
f : ↥(span 𝕜 {x}) →L[𝕜] 𝕜 := ↑‖x‖ • coord 𝕜 x h
g : E →L[𝕜] 𝕜
hg : (∀ (x : ↥p), g ↑x = f x) ∧ ‖g‖ = ‖f‖
⊢ g ↑{ val := x, property := (_ : x ∈ span 𝕜 {x}) } =
    (↑‖x‖ • coord 𝕜 x h) { val := x, property := (_ : x ∈ span 𝕜 {x}) }

Next tactic:
rw [← hg.1]
/-- Corollary of Hahn-Banach. Given a nonzero element `x` of a normed space, there exists an
    element of the dual space, of norm `1`, whose value on `x` is `‖x‖`. -/
theorem exists_dual_vector (x : E) (h : x ≠ 0) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  let p : Submodule 𝕜 E := 𝕜 ∙ x
  let f := (‖x‖ : 𝕜) • coord 𝕜 x h
  obtain ⟨g, hg⟩ := exists_extension_norm_eq p f
  refine' ⟨g, _, _⟩
  · rw [hg.2, coord_norm']
  · calc
      g x = g (⟨x, mem_span_singleton_self x⟩ : 𝕜 ∙ x) := by rw [coe_mk]
      _ = ((‖x‖ : 𝕜) • coord 𝕜 x h) (⟨x, mem_span_singleton_self x⟩ : 𝕜 ∙ x) := by rw [← hg.1]
      _ = ‖x‖ := by 

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : x ≠ 0
p : Submodule 𝕜 E := span 𝕜 {x}
f : ↥(span 𝕜 {x}) →L[𝕜] 𝕜 := ↑‖x‖ • coord 𝕜 x h
g : E →L[𝕜] 𝕜
hg : (∀ (x : ↥p), g ↑x = f x) ∧ ‖g‖ = ‖f‖
⊢ (↑‖x‖ • coord 𝕜 x h) { val := x, property := (_ : x ∈ span 𝕜 {x}) } = ↑‖x‖

Next tactic:
simp
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, and choosing
    the dual element arbitrarily when `x = 0`. -/
theorem exists_dual_vector' [Nontrivial E] (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  

Proof state:
𝕜 : Type v
inst✝³ : IsROrC 𝕜
E : Type u
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace 𝕜 E
inst✝ : Nontrivial E
x : E
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
by_cases hx : x = 0
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, and choosing
    the dual element arbitrarily when `x = 0`. -/
theorem exists_dual_vector' [Nontrivial E] (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · 

Proof state:
case pos
𝕜 : Type v
inst✝³ : IsROrC 𝕜
E : Type u
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace 𝕜 E
inst✝ : Nontrivial E
x : E
hx : x = 0
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
obtain ⟨y, hy⟩ := exists_ne (0 : E)
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, and choosing
    the dual element arbitrarily when `x = 0`. -/
theorem exists_dual_vector' [Nontrivial E] (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · obtain ⟨y, hy⟩ := exists_ne (0 : E)
    

Proof state:
case pos.intro
𝕜 : Type v
inst✝³ : IsROrC 𝕜
E : Type u
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace 𝕜 E
inst✝ : Nontrivial E
x : E
hx : x = 0
y : E
hy : y ≠ 0
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
obtain ⟨g, hg⟩ : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g y = ‖y‖ := exists_dual_vector 𝕜 y hy
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, and choosing
    the dual element arbitrarily when `x = 0`. -/
theorem exists_dual_vector' [Nontrivial E] (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · obtain ⟨y, hy⟩ := exists_ne (0 : E)
    obtain ⟨g, hg⟩ : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g y = ‖y‖ := exists_dual_vector 𝕜 y hy
    

Proof state:
case pos.intro.intro
𝕜 : Type v
inst✝³ : IsROrC 𝕜
E : Type u
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace 𝕜 E
inst✝ : Nontrivial E
x : E
hx : x = 0
y : E
hy : y ≠ 0
g : E →L[𝕜] 𝕜
hg : ‖g‖ = 1 ∧ g y = ↑‖y‖
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
refine' ⟨g, hg.left, _⟩
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, and choosing
    the dual element arbitrarily when `x = 0`. -/
theorem exists_dual_vector' [Nontrivial E] (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · obtain ⟨y, hy⟩ := exists_ne (0 : E)
    obtain ⟨g, hg⟩ : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g y = ‖y‖ := exists_dual_vector 𝕜 y hy
    refine' ⟨g, hg.left, _⟩
    

Proof state:
case pos.intro.intro
𝕜 : Type v
inst✝³ : IsROrC 𝕜
E : Type u
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace 𝕜 E
inst✝ : Nontrivial E
x : E
hx : x = 0
y : E
hy : y ≠ 0
g : E →L[𝕜] 𝕜
hg : ‖g‖ = 1 ∧ g y = ↑‖y‖
⊢ g x = ↑‖x‖

Next tactic:
simp [hx]
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, and choosing
    the dual element arbitrarily when `x = 0`. -/
theorem exists_dual_vector' [Nontrivial E] (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · obtain ⟨y, hy⟩ := exists_ne (0 : E)
    obtain ⟨g, hg⟩ : ∃ g : E →L[𝕜] 𝕜, ‖g‖ = 1 ∧ g y = ‖y‖ := exists_dual_vector 𝕜 y hy
    refine' ⟨g, hg.left, _⟩
    simp [hx]
  · 

Proof state:
case neg
𝕜 : Type v
inst✝³ : IsROrC 𝕜
E : Type u
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace 𝕜 E
inst✝ : Nontrivial E
x : E
hx : ¬x = 0
⊢ ∃ g, ‖g‖ = 1 ∧ g x = ↑‖x‖

Next tactic:
exact exists_dual_vector 𝕜 x hx
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, but only ensuring that
    the dual element has norm at most `1` (this can not be improved for the trivial
    vector space). -/
theorem exists_dual_vector'' (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖x‖ := by
  

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
⊢ ∃ g, ‖g‖ ≤ 1 ∧ g x = ↑‖x‖

Next tactic:
by_cases hx : x = 0
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, but only ensuring that
    the dual element has norm at most `1` (this can not be improved for the trivial
    vector space). -/
theorem exists_dual_vector'' (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · 

Proof state:
case pos
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
hx : x = 0
⊢ ∃ g, ‖g‖ ≤ 1 ∧ g x = ↑‖x‖

Next tactic:
refine' ⟨0, by simp, _⟩
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, but only ensuring that
    the dual element has norm at most `1` (this can not be improved for the trivial
    vector space). -/
theorem exists_dual_vector'' (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · refine' ⟨0, by 

Proof state:
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
hx : x = 0
⊢ ‖0‖ ≤ 1

Next tactic:
simp
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, but only ensuring that
    the dual element has norm at most `1` (this can not be improved for the trivial
    vector space). -/
theorem exists_dual_vector'' (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · refine' ⟨0, by simp, _⟩
    

Proof state:
case pos
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
hx : x = 0
⊢ 0 x = ↑‖x‖

Next tactic:
symm
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, but only ensuring that
    the dual element has norm at most `1` (this can not be improved for the trivial
    vector space). -/
theorem exists_dual_vector'' (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · refine' ⟨0, by simp, _⟩
    symm
    

Proof state:
case pos
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
hx : x = 0
⊢ ↑‖x‖ = 0 x

Next tactic:
simp [hx]
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, but only ensuring that
    the dual element has norm at most `1` (this can not be improved for the trivial
    vector space). -/
theorem exists_dual_vector'' (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · refine' ⟨0, by simp, _⟩
    symm
    simp [hx]
  · 

Proof state:
case neg
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
hx : ¬x = 0
⊢ ∃ g, ‖g‖ ≤ 1 ∧ g x = ↑‖x‖

Next tactic:
rcases exists_dual_vector 𝕜 x hx with ⟨g, g_norm, g_eq⟩
/-- Variant of Hahn-Banach, eliminating the hypothesis that `x` be nonzero, but only ensuring that
    the dual element has norm at most `1` (this can not be improved for the trivial
    vector space). -/
theorem exists_dual_vector'' (x : E) : ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖x‖ := by
  by_cases hx : x = 0
  · refine' ⟨0, by simp, _⟩
    symm
    simp [hx]
  · rcases exists_dual_vector 𝕜 x hx with ⟨g, g_norm, g_eq⟩
    

Proof state:
case neg.intro.intro
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
hx : ¬x = 0
g : E →L[𝕜] 𝕜
g_norm : ‖g‖ = 1
g_eq : g x = ↑‖x‖
⊢ ∃ g, ‖g‖ ≤ 1 ∧ g x = ↑‖x‖

Next tactic:
exact ⟨g, g_norm.le, g_eq⟩
/-- The isomorphism `(Γ₀.splitting K).nondegComplex ≅ K` for all `K : ChainComplex C ℕ`. -/
@[simps!]
def Γ₀NondegComplexIso (K : ChainComplex C ℕ) : (Γ₀.splitting K).nondegComplex ≅ K :=
  HomologicalComplex.Hom.isoOfComponents (fun n => Iso.refl _)
    (by
      

Proof state:
C : Type u_1
inst✝² : Category.{?u.42, u_1} C
inst✝¹ : Preadditive C
inst✝ : HasFiniteCoproducts C
K : ChainComplex C ℕ
⊢ ∀ (i j : ℕ),
    ComplexShape.Rel (ComplexShape.down ℕ) i j →
      ((fun n => Iso.refl (HomologicalComplex.X (Splitting.nondegComplex (Γ₀.splitting K)) n)) i).hom ≫
          HomologicalComplex.d K i j =
        HomologicalComplex.d (Splitting.nondegComplex (Γ₀.splitting K)) i j ≫
          ((fun n => Iso.refl (HomologicalComplex.X (Splitting.nondegComplex (Γ₀.splitting K)) n)) j).hom

Next tactic:
rintro _ n (rfl : n + 1 = _)
/-- The isomorphism `(Γ₀.splitting K).nondegComplex ≅ K` for all `K : ChainComplex C ℕ`. -/
@[simps!]
def Γ₀NondegComplexIso (K : ChainComplex C ℕ) : (Γ₀.splitting K).nondegComplex ≅ K :=
  HomologicalComplex.Hom.isoOfComponents (fun n => Iso.refl _)
    (by
      rintro _ n (rfl : n + 1 = _)
      

Proof state:
C : Type u_1
inst✝² : Category.{?u.42, u_1} C
inst✝¹ : Preadditive C
inst✝ : HasFiniteCoproducts C
K : ChainComplex C ℕ
n : ℕ
⊢ ((fun n => Iso.refl (HomologicalComplex.X (Splitting.nondegComplex (Γ₀.splitting K)) n)) (n + 1)).hom ≫
      HomologicalComplex.d K (n + 1) n =
    HomologicalComplex.d (Splitting.nondegComplex (Γ₀.splitting K)) (n + 1) n ≫
      ((fun n => Iso.refl (HomologicalComplex.X (Splitting.nondegComplex (Γ₀.splitting K)) n)) n).hom

Next tactic:
dsimp
/-- The isomorphism `(Γ₀.splitting K).nondegComplex ≅ K` for all `K : ChainComplex C ℕ`. -/
@[simps!]
def Γ₀NondegComplexIso (K : ChainComplex C ℕ) : (Γ₀.splitting K).nondegComplex ≅ K :=
  HomologicalComplex.Hom.isoOfComponents (fun n => Iso.refl _)
    (by
      rintro _ n (rfl : n + 1 = _)
      dsimp
      

Proof state:
C : Type u_1
inst✝² : Category.{?u.42, u_1} C
inst✝¹ : Preadditive C
inst✝ : HasFiniteCoproducts C
K : ChainComplex C ℕ
n : ℕ
⊢ 𝟙 (Splitting.N (Γ₀.splitting K) (n + 1)) ≫ HomologicalComplex.d K (n + 1) n =
    (Splitting.ιSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n + 1])) ≫
        HomologicalComplex.d (AlternatingFaceMapComplex.obj (Γ₀.obj K)) (n + 1) n ≫
          Splitting.πSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n]))) ≫
      𝟙 (Splitting.N (Γ₀.splitting K) n)

Next tactic:
simp only [id_comp, comp_id, AlternatingFaceMapComplex.obj_d_eq, Preadditive.sum_comp,
        Preadditive.comp_sum]
/-- The isomorphism `(Γ₀.splitting K).nondegComplex ≅ K` for all `K : ChainComplex C ℕ`. -/
@[simps!]
def Γ₀NondegComplexIso (K : ChainComplex C ℕ) : (Γ₀.splitting K).nondegComplex ≅ K :=
  HomologicalComplex.Hom.isoOfComponents (fun n => Iso.refl _)
    (by
      rintro _ n (rfl : n + 1 = _)
      dsimp
      simp only [id_comp, comp_id, AlternatingFaceMapComplex.obj_d_eq, Preadditive.sum_comp,
        Preadditive.comp_sum]
      

Proof state:
C : Type u_1
inst✝² : Category.{?u.42, u_1} C
inst✝¹ : Preadditive C
inst✝ : HasFiniteCoproducts C
K : ChainComplex C ℕ
n : ℕ
⊢ HomologicalComplex.d K (n + 1) n =
    Finset.sum Finset.univ fun j =>
      Splitting.ιSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n + 1])) ≫
        ((-1) ^ ↑j • δ (Γ₀.obj K) j) ≫ Splitting.πSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n]))

Next tactic:
rw [Fintype.sum_eq_single (0 : Fin (n + 2))]
/-- The isomorphism `(Γ₀.splitting K).nondegComplex ≅ K` for all `K : ChainComplex C ℕ`. -/
@[simps!]
def Γ₀NondegComplexIso (K : ChainComplex C ℕ) : (Γ₀.splitting K).nondegComplex ≅ K :=
  HomologicalComplex.Hom.isoOfComponents (fun n => Iso.refl _)
    (by
      rintro _ n (rfl : n + 1 = _)
      dsimp
      simp only [id_comp, comp_id, AlternatingFaceMapComplex.obj_d_eq, Preadditive.sum_comp,
        Preadditive.comp_sum]
      rw [Fintype.sum_eq_single (0 : Fin (n + 2))]
      · 

Proof state:
C : Type u_1
inst✝² : Category.{?u.42, u_1} C
inst✝¹ : Preadditive C
inst✝ : HasFiniteCoproducts C
K : ChainComplex C ℕ
n : ℕ
⊢ HomologicalComplex.d K (n + 1) n =
    Splitting.ιSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n + 1])) ≫
      ((-1) ^ ↑0 • δ (Γ₀.obj K) 0) ≫ Splitting.πSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n]))

Next tactic:
simp only [Fin.val_zero, pow_zero, one_zsmul]
/-- The isomorphism `(Γ₀.splitting K).nondegComplex ≅ K` for all `K : ChainComplex C ℕ`. -/
@[simps!]
def Γ₀NondegComplexIso (K : ChainComplex C ℕ) : (Γ₀.splitting K).nondegComplex ≅ K :=
  HomologicalComplex.Hom.isoOfComponents (fun n => Iso.refl _)
    (by
      rintro _ n (rfl : n + 1 = _)
      dsimp
      simp only [id_comp, comp_id, AlternatingFaceMapComplex.obj_d_eq, Preadditive.sum_comp,
        Preadditive.comp_sum]
      rw [Fintype.sum_eq_single (0 : Fin (n + 2))]
      · simp only [Fin.val_zero, pow_zero, one_zsmul]
        

Proof state:
C : Type u_1
inst✝² : Category.{?u.42, u_1} C
inst✝¹ : Preadditive C
inst✝ : HasFiniteCoproducts C
K : ChainComplex C ℕ
n : ℕ
⊢ HomologicalComplex.d K (n + 1) n =
    Splitting.ιSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n + 1])) ≫
      δ (Γ₀.obj K) 0 ≫ Splitting.πSummand (Γ₀.splitting K) (Splitting.IndexSet.id (op [n]))

Next tactic:
erw [Γ₀.Obj.mapMono_on_summand_id_assoc, Γ₀.Obj.Termwise.mapMono_δ₀,
          Splitting.ι_πSummand_eq_id, comp_id]