l3lab/ntp-mathlib huggingface dataset:
/-- Reflection in a complete subspace of an inner product space.  The word "reflection" is
sometimes understood to mean specifically reflection in a codimension-one subspace, and sometimes
more generally to cover operations such as reflection in a point.  The definition here, of
reflection in a subspace, is a more general sense of the word that includes both those common
cases. -/
def reflection : E ≃ₗᵢ[𝕜] E :=
  { reflectionLinearEquiv K with
    norm_map' := by
      intro x
      dsimp only
      let w : K := orthogonalProjection K x
      let v := x - w
      have : ⟪v, w⟫ = 0 := orthogonalProjection_inner_eq_zero x w w.2
      

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
src✝ : E ≃ₗ[𝕜] E := reflectionLinearEquiv K
x : E
w : ↥K := (orthogonalProjection K) x
v : E := x - ↑w
this : inner v ↑w = 0
⊢ ‖{ toLinearMap := ↑(reflectionLinearEquiv K), invFun := (reflectionLinearEquiv K).invFun,
          left_inv :=
            (_ : Function.LeftInverse (reflectionLinearEquiv K).invFun (↑(reflectionLinearEquiv K)).toAddHom.toFun),
          right_inv :=
            (_ : Function.RightInverse (reflectionLinearEquiv K).invFun (↑(reflectionLinearEquiv K)).toAddHom.toFun) }
        x‖ =
    ‖x‖

Next tactic:
convert norm_sub_eq_norm_add this using 2
/-- Reflection in a complete subspace of an inner product space.  The word "reflection" is
sometimes understood to mean specifically reflection in a codimension-one subspace, and sometimes
more generally to cover operations such as reflection in a point.  The definition here, of
reflection in a subspace, is a more general sense of the word that includes both those common
cases. -/
def reflection : E ≃ₗᵢ[𝕜] E :=
  { reflectionLinearEquiv K with
    norm_map' := by
      intro x
      dsimp only
      let w : K := orthogonalProjection K x
      let v := x - w
      have : ⟪v, w⟫ = 0 := orthogonalProjection_inner_eq_zero x w w.2
      convert norm_sub_eq_norm_add this using 2
      · 

Proof state:
case h.e'_2.h.e'_3
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
src✝ : E ≃ₗ[𝕜] E := reflectionLinearEquiv K
x : E
w : ↥K := (orthogonalProjection K) x
v : E := x - ↑w
this : inner v ↑w = 0
⊢ { toLinearMap := ↑(reflectionLinearEquiv K), invFun := (reflectionLinearEquiv K).invFun,
        left_inv :=
          (_ : Function.LeftInverse (reflectionLinearEquiv K).invFun (↑(reflectionLinearEquiv K)).toAddHom.toFun),
        right_inv :=
          (_ : Function.RightInverse (reflectionLinearEquiv K).invFun (↑(reflectionLinearEquiv K)).toAddHom.toFun) }
      x =
    ↑w - v

Next tactic:
rw [LinearEquiv.coe_mk, reflectionLinearEquiv, LinearEquiv.toFun_eq_coe,
          LinearEquiv.coe_ofInvolutive, LinearMap.sub_apply, LinearMap.id_apply, two_smul,
          LinearMap.add_apply, LinearMap.comp_apply, Submodule.subtype_apply,
          ContinuousLinearMap.coe_coe]
/-- Reflection in a complete subspace of an inner product space.  The word "reflection" is
sometimes understood to mean specifically reflection in a codimension-one subspace, and sometimes
more generally to cover operations such as reflection in a point.  The definition here, of
reflection in a subspace, is a more general sense of the word that includes both those common
cases. -/
def reflection : E ≃ₗᵢ[𝕜] E :=
  { reflectionLinearEquiv K with
    norm_map' := by
      intro x
      dsimp only
      let w : K := orthogonalProjection K x
      let v := x - w
      have : ⟪v, w⟫ = 0 := orthogonalProjection_inner_eq_zero x w w.2
      convert norm_sub_eq_norm_add this using 2
      · rw [LinearEquiv.coe_mk, reflectionLinearEquiv, LinearEquiv.toFun_eq_coe,
          LinearEquiv.coe_ofInvolutive, LinearMap.sub_apply, LinearMap.id_apply, two_smul,
          LinearMap.add_apply, LinearMap.comp_apply, Submodule.subtype_apply,
          ContinuousLinearMap.coe_coe]
        

Proof state:
case h.e'_2.h.e'_3
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
src✝ : E ≃ₗ[𝕜] E := reflectionLinearEquiv K
x : E
w : ↥K := (orthogonalProjection K) x
v : E := x - ↑w
this : inner v ↑w = 0
⊢ ↑((orthogonalProjection K) x) + ↑((orthogonalProjection K) x) - x = ↑w - v

Next tactic:
dsimp
/-- Reflection in a complete subspace of an inner product space.  The word "reflection" is
sometimes understood to mean specifically reflection in a codimension-one subspace, and sometimes
more generally to cover operations such as reflection in a point.  The definition here, of
reflection in a subspace, is a more general sense of the word that includes both those common
cases. -/
def reflection : E ≃ₗᵢ[𝕜] E :=
  { reflectionLinearEquiv K with
    norm_map' := by
      intro x
      dsimp only
      let w : K := orthogonalProjection K x
      let v := x - w
      have : ⟪v, w⟫ = 0 := orthogonalProjection_inner_eq_zero x w w.2
      convert norm_sub_eq_norm_add this using 2
      · rw [LinearEquiv.coe_mk, reflectionLinearEquiv, LinearEquiv.toFun_eq_coe,
          LinearEquiv.coe_ofInvolutive, LinearMap.sub_apply, LinearMap.id_apply, two_smul,
          LinearMap.add_apply, LinearMap.comp_apply, Submodule.subtype_apply,
          ContinuousLinearMap.coe_coe]
        dsimp
        

Proof state:
case h.e'_2.h.e'_3
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
src✝ : E ≃ₗ[𝕜] E := reflectionLinearEquiv K
x : E
w : ↥K := (orthogonalProjection K) x
v : E := x - ↑w
this : inner v ↑w = 0
⊢ ↑((orthogonalProjection K) x) + ↑((orthogonalProjection K) x) - x =
    ↑((orthogonalProjection K) x) - (x - ↑((orthogonalProjection K) x))

Next tactic:
abel
/-- Reflection in a complete subspace of an inner product space.  The word "reflection" is
sometimes understood to mean specifically reflection in a codimension-one subspace, and sometimes
more generally to cover operations such as reflection in a point.  The definition here, of
reflection in a subspace, is a more general sense of the word that includes both those common
cases. -/
def reflection : E ≃ₗᵢ[𝕜] E :=
  { reflectionLinearEquiv K with
    norm_map' := by
      intro x
      dsimp only
      let w : K := orthogonalProjection K x
      let v := x - w
      have : ⟪v, w⟫ = 0 := orthogonalProjection_inner_eq_zero x w w.2
      convert norm_sub_eq_norm_add this using 2
      · rw [LinearEquiv.coe_mk, reflectionLinearEquiv, LinearEquiv.toFun_eq_coe,
          LinearEquiv.coe_ofInvolutive, LinearMap.sub_apply, LinearMap.id_apply, two_smul,
          LinearMap.add_apply, LinearMap.comp_apply, Submodule.subtype_apply,
          ContinuousLinearMap.coe_coe]
        dsimp
        abel
      · 

Proof state:
case h.e'_3.h.e'_3
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
src✝ : E ≃ₗ[𝕜] E := reflectionLinearEquiv K
x : E
w : ↥K := (orthogonalProjection K) x
v : E := x - ↑w
this : inner v ↑w = 0
⊢ x = ↑w + v

Next tactic:
simp only [add_sub_cancel'_right, eq_self_iff_true]
theorem reflection_orthogonal_apply (v : E) : reflection Kᗮ v = -reflection K v := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
v : E
⊢ (reflection Kᗮ) v = -(reflection K) v

Next tactic:
simp [reflection_apply]
theorem reflection_orthogonal_apply (v : E) : reflection Kᗮ v = -reflection K v := by
  simp [reflection_apply]; 

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
v : E
⊢ 2 • v - 2 • ↑((orthogonalProjection K) v) - v = v - 2 • ↑((orthogonalProjection K) v)

Next tactic:
abel
theorem reflection_orthogonal : reflection Kᗮ = .trans (reflection K) (.neg _) := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
⊢ reflection Kᗮ = LinearIsometryEquiv.trans (reflection K) (LinearIsometryEquiv.neg 𝕜)

Next tactic:
ext
theorem reflection_orthogonal : reflection Kᗮ = .trans (reflection K) (.neg _) := by
  ext; 

Proof state:
case h
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
x✝ : E
⊢ (reflection Kᗮ) x✝ = (LinearIsometryEquiv.trans (reflection K) (LinearIsometryEquiv.neg 𝕜)) x✝

Next tactic:
apply reflection_orthogonal_apply
theorem reflection_singleton_apply (u v : E) :
    reflection (𝕜 ∙ u) v = 2 • (⟪u, v⟫ / ((‖u‖ : 𝕜) ^ 2)) • u - v := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
u v : E
⊢ (reflection (Submodule.span 𝕜 {u})) v = 2 • (inner u v / ↑‖u‖ ^ 2) • u - v

Next tactic:
rw [reflection_apply, orthogonalProjection_singleton, ofReal_pow]
/-- A point is its own reflection if and only if it is in the subspace. -/
theorem reflection_eq_self_iff (x : E) : reflection K x = x ↔ x ∈ K := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
x : E
⊢ (reflection K) x = x ↔ x ∈ K

Next tactic:
rw [← orthogonalProjection_eq_self_iff, reflection_apply, sub_eq_iff_eq_add', ← two_smul 𝕜,
    two_smul ℕ, ← two_smul 𝕜]
/-- A point is its own reflection if and only if it is in the subspace. -/
theorem reflection_eq_self_iff (x : E) : reflection K x = x ↔ x ∈ K := by
  rw [← orthogonalProjection_eq_self_iff, reflection_apply, sub_eq_iff_eq_add', ← two_smul 𝕜,
    two_smul ℕ, ← two_smul 𝕜]
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
x : E
⊢ 2 • ↑((orthogonalProjection K) x) = 2 • x ↔ ↑((orthogonalProjection K) x) = x

Next tactic:
refine' (smul_right_injective E _).eq_iff
/-- A point is its own reflection if and only if it is in the subspace. -/
theorem reflection_eq_self_iff (x : E) : reflection K x = x ↔ x ∈ K := by
  rw [← orthogonalProjection_eq_self_iff, reflection_apply, sub_eq_iff_eq_add', ← two_smul 𝕜,
    two_smul ℕ, ← two_smul 𝕜]
  refine' (smul_right_injective E _).eq_iff
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
x : E
⊢ 2 ≠ 0

Next tactic:
exact two_ne_zero
/-- Reflection in the `Submodule.map` of a subspace. -/
theorem reflection_map_apply {E E' : Type*} [NormedAddCommGroup E] [NormedAddCommGroup E']
    [InnerProductSpace 𝕜 E] [InnerProductSpace 𝕜 E'] (f : E ≃ₗᵢ[𝕜] E') (K : Submodule 𝕜 E)
    [HasOrthogonalProjection K] (x : E') :
    reflection (K.map (f.toLinearEquiv : E →ₗ[𝕜] E')) x = f (reflection K (f.symm x)) := by
  

Proof state:
𝕜 : Type u_1
E✝ : Type u_2
F : Type u_3
inst✝¹⁰ : IsROrC 𝕜
inst✝⁹ : NormedAddCommGroup E✝
inst✝⁸ : NormedAddCommGroup F
inst✝⁷ : InnerProductSpace 𝕜 E✝
inst✝⁶ : InnerProductSpace ℝ F
K✝ : Submodule 𝕜 E✝
inst✝⁵ : HasOrthogonalProjection K✝
E : Type u_4
E' : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup E'
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace 𝕜 E'
f : E ≃ₗᵢ[𝕜] E'
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
x : E'
⊢ (reflection (Submodule.map (↑f.toLinearEquiv) K)) x = f ((reflection K) ((LinearIsometryEquiv.symm f) x))

Next tactic:
simp [two_smul, reflection_apply, orthogonalProjection_map_apply f K x]
/-- Reflection through the trivial subspace {0} is just negation. -/
@[simp]
theorem reflection_bot : reflection (⊥ : Submodule 𝕜 E) = LinearIsometryEquiv.neg 𝕜 := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
⊢ reflection ⊥ = LinearIsometryEquiv.neg 𝕜

Next tactic:
ext
/-- Reflection through the trivial subspace {0} is just negation. -/
@[simp]
theorem reflection_bot : reflection (⊥ : Submodule 𝕜 E) = LinearIsometryEquiv.neg 𝕜 := by
  ext; 

Proof state:
case h
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
x✝ : E
⊢ (reflection ⊥) x✝ = (LinearIsometryEquiv.neg 𝕜) x✝

Next tactic:
simp [reflection_apply]
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
⊢ K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂

Next tactic:
ext x
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  ext x
  

Proof state:
case h
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
x : E
⊢ x ∈ K₁ ⊔ K₁ᗮ ⊓ K₂ ↔ x ∈ K₂

Next tactic:
rw [Submodule.mem_sup]
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  ext x
  rw [Submodule.mem_sup]
  

Proof state:
case h
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
x : E
⊢ (∃ y ∈ K₁, ∃ z ∈ K₁ᗮ ⊓ K₂, y + z = x) ↔ x ∈ K₂

Next tactic:
let v : K₁ := orthogonalProjection K₁ x
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  ext x
  rw [Submodule.mem_sup]
  let v : K₁ := orthogonalProjection K₁ x
  

Proof state:
case h
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
x : E
v : ↥K₁ := (orthogonalProjection K₁) x
⊢ (∃ y ∈ K₁, ∃ z ∈ K₁ᗮ ⊓ K₂, y + z = x) ↔ x ∈ K₂

Next tactic:
have hvm : x - v ∈ K₁ᗮ := sub_orthogonalProjection_mem_orthogonal x
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  ext x
  rw [Submodule.mem_sup]
  let v : K₁ := orthogonalProjection K₁ x
  have hvm : x - v ∈ K₁ᗮ := sub_orthogonalProjection_mem_orthogonal x
  

Proof state:
case h
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
x : E
v : ↥K₁ := (orthogonalProjection K₁) x
hvm : x - ↑v ∈ K₁ᗮ
⊢ (∃ y ∈ K₁, ∃ z ∈ K₁ᗮ ⊓ K₂, y + z = x) ↔ x ∈ K₂

Next tactic:
constructor
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  ext x
  rw [Submodule.mem_sup]
  let v : K₁ := orthogonalProjection K₁ x
  have hvm : x - v ∈ K₁ᗮ := sub_orthogonalProjection_mem_orthogonal x
  constructor
  · 

Proof state:
case h.mp
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
x : E
v : ↥K₁ := (orthogonalProjection K₁) x
hvm : x - ↑v ∈ K₁ᗮ
⊢ (∃ y ∈ K₁, ∃ z ∈ K₁ᗮ ⊓ K₂, y + z = x) → x ∈ K₂

Next tactic:
rintro ⟨y, hy, z, hz, rfl⟩
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  ext x
  rw [Submodule.mem_sup]
  let v : K₁ := orthogonalProjection K₁ x
  have hvm : x - v ∈ K₁ᗮ := sub_orthogonalProjection_mem_orthogonal x
  constructor
  · rintro ⟨y, hy, z, hz, rfl⟩
    

Proof state:
case h.mp.intro.intro.intro.intro
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
y : E
hy : y ∈ K₁
z : E
hz : z ∈ K₁ᗮ ⊓ K₂
v : ↥K₁ := (orthogonalProjection K₁) (y + z)
hvm : y + z - ↑v ∈ K₁ᗮ
⊢ y + z ∈ K₂

Next tactic:
exact K₂.add_mem (h hy) hz.2
/-- If `K₁` is complete and contained in `K₂`, `K₁` and `K₁ᗮ ⊓ K₂` span `K₂`. -/
theorem Submodule.sup_orthogonal_inf_of_completeSpace {K₁ K₂ : Submodule 𝕜 E} (h : K₁ ≤ K₂)
    [HasOrthogonalProjection K₁] : K₁ ⊔ K₁ᗮ ⊓ K₂ = K₂ := by
  ext x
  rw [Submodule.mem_sup]
  let v : K₁ := orthogonalProjection K₁ x
  have hvm : x - v ∈ K₁ᗮ := sub_orthogonalProjection_mem_orthogonal x
  constructor
  · rintro ⟨y, hy, z, hz, rfl⟩
    exact K₂.add_mem (h hy) hz.2
  · 

Proof state:
case h.mpr
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K K₁ K₂ : Submodule 𝕜 E
h : K₁ ≤ K₂
inst✝ : HasOrthogonalProjection K₁
x : E
v : ↥K₁ := (orthogonalProjection K₁) x
hvm : x - ↑v ∈ K₁ᗮ
⊢ x ∈ K₂ → ∃ y ∈ K₁, ∃ z ∈ K₁ᗮ ⊓ K₂, y + z = x

Next tactic:
exact fun hx => ⟨v, v.prop, x - v, ⟨hvm, K₂.sub_mem hx (h v.prop)⟩, add_sub_cancel'_right _ _⟩
/-- If `K` is complete, `K` and `Kᗮ` span the whole space. -/
theorem Submodule.sup_orthogonal_of_completeSpace [HasOrthogonalProjection K] : K ⊔ Kᗮ = ⊤ := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
⊢ K ⊔ Kᗮ = ⊤

Next tactic:
convert Submodule.sup_orthogonal_inf_of_completeSpace (le_top : K ≤ ⊤) using 2
/-- If `K` is complete, `K` and `Kᗮ` span the whole space. -/
theorem Submodule.sup_orthogonal_of_completeSpace [HasOrthogonalProjection K] : K ⊔ Kᗮ = ⊤ := by
  convert Submodule.sup_orthogonal_inf_of_completeSpace (le_top : K ≤ ⊤) using 2
  

Proof state:
case h.e'_2.h.e'_4
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
⊢ Kᗮ = Kᗮ ⊓ ⊤

Next tactic:
simp
/-- If `K` is complete, any `v` in `E` can be expressed as a sum of elements of `K` and `Kᗮ`. -/
theorem Submodule.exists_add_mem_mem_orthogonal [HasOrthogonalProjection K] (v : E) :
    ∃ y ∈ K, ∃ z ∈ Kᗮ, v = y + z :=
  ⟨orthogonalProjection K v, Subtype.coe_prop _, v - orthogonalProjection K v,
    sub_orthogonalProjection_mem_orthogonal _, by 

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
v : E
⊢ v = ↑((orthogonalProjection K) v) + (v - ↑((orthogonalProjection K) v))

Next tactic:
simp
/-- If `K` admits an orthogonal projection, then the orthogonal complement of its orthogonal
complement is itself. -/
@[simp]
theorem Submodule.orthogonal_orthogonal [HasOrthogonalProjection K] : Kᗮᗮ = K := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
⊢ Kᗮᗮ = K

Next tactic:
ext v
/-- If `K` admits an orthogonal projection, then the orthogonal complement of its orthogonal
complement is itself. -/
@[simp]
theorem Submodule.orthogonal_orthogonal [HasOrthogonalProjection K] : Kᗮᗮ = K := by
  ext v
  

Proof state:
case h
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
v : E
⊢ v ∈ Kᗮᗮ ↔ v ∈ K

Next tactic:
constructor
/-- If `K` admits an orthogonal projection, then the orthogonal complement of its orthogonal
complement is itself. -/
@[simp]
theorem Submodule.orthogonal_orthogonal [HasOrthogonalProjection K] : Kᗮᗮ = K := by
  ext v
  constructor
  · 

Proof state:
case h.mp
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
v : E
⊢ v ∈ Kᗮᗮ → v ∈ K

Next tactic:
obtain ⟨y, hy, z, hz, rfl⟩ := K.exists_add_mem_mem_orthogonal v
/-- If `K` admits an orthogonal projection, then the orthogonal complement of its orthogonal
complement is itself. -/
@[simp]
theorem Submodule.orthogonal_orthogonal [HasOrthogonalProjection K] : Kᗮᗮ = K := by
  ext v
  constructor
  · obtain ⟨y, hy, z, hz, rfl⟩ := K.exists_add_mem_mem_orthogonal v
    

Proof state:
case h.mp.intro.intro.intro.intro
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁵ : IsROrC 𝕜
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace 𝕜 E
inst✝¹ : InnerProductSpace ℝ F
K : Submodule 𝕜 E
inst✝ : HasOrthogonalProjection K
y : E
hy : y ∈ K
z : E
hz : z ∈ Kᗮ
⊢ y + z ∈ Kᗮᗮ → y + z ∈ K

Next tactic:
intro hv