Theorem: IsLprojection.commute
File: Mathlib/Analysis/NormedSpace/MStructure.lean

tactic: have PR_eq_RPR : ∀ R : M, IsLprojection X R → P * R = R * P * R := fun R h₃ => by
  refine @eq_of_smul_eq_smul _ X _ _ _ _ fun x => by
    rw [← norm_sub_eq_zero_iff]
    have e1 : ‖R • x‖ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ :=
      calc
        ‖R • x‖ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
            (‖(R * R) • x - R • P • R • x‖ + ‖(1 - R) • (1 - P) • R • x‖) := by
          rw [h₁.Lnorm, h₃.Lnorm, h₃.Lnorm ((1 - P) • R • x), sub_smul 1 P, one_smul, smul_sub,
            mul_smul]
        _ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
            (‖R • x - R • P • R • x‖ + ‖((1 - R) * R) • x - (1 - R) • P • R • x‖) := by
          rw [h₃.proj.eq, sub_smul 1 P, one_smul, smul_sub, mul_smul]
        _ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
            (‖R • x - R • P • R • x‖ + ‖(1 - R) • P • R • x‖) := by
          rw [sub_mul, h₃.proj.eq, one_mul, sub_self, zero_smul, zero_sub, norm_neg]
        _ = ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖ := by abel
        _ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ := by
          rw [GE.ge]
          have :=
            add_le_add_right (norm_le_insert' (R • x) (R • P • R • x)) (2 • ‖(1 - R) • P • R • x‖)
          simpa only [mul_smul, sub_smul, one_smul] using this
    rw [GE.ge] at e1
    nth_rewrite 2 [← add_zero ‖R • x‖]  at e1
    rw [add_le_add_iff_left, two_smul, ← two_mul] at e1
    rw [le_antisymm_iff]
    refine' ⟨_, norm_nonneg _⟩
    rwa [← MulZeroClass.mul_zero (2 : ℝ), mul_le_mul_left (show (0 : ℝ) < 2 by norm_num)] at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
⊢ Commute P Q

tactic: have QP_eq_QPQ : Q * P = Q * P * Q := by
  have e1 : P * (1 - Q) = P * (1 - Q) - (Q * P - Q * P * Q) :=
    calc
      P * (1 - Q) = (1 - Q) * P * (1 - Q) := by rw [PR_eq_RPR (1 - Q) h₂.Lcomplement]
      _ = P * (1 - Q) - (Q * P - Q * P * Q) := by noncomm_ring
  rwa [eq_sub_iff_add_eq, add_right_eq_self, sub_eq_zero] at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
PR_eq_RPR : ∀ (R : M), IsLprojection X R → P * R = R * P * R
⊢ Commute P Q

tactic: show P * Q = Q * P
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
PR_eq_RPR : ∀ (R : M), IsLprojection X R → P * R = R * P * R
QP_eq_QPQ : Q * P = Q * P * Q
⊢ Commute P Q

tactic: refine @eq_of_smul_eq_smul _ X _ _ _ _ fun x => by
  rw [← norm_sub_eq_zero_iff]
  have e1 : ‖R • x‖ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ :=
    calc
      ‖R • x‖ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
          (‖(R * R) • x - R • P • R • x‖ + ‖(1 - R) • (1 - P) • R • x‖) := by
        rw [h₁.Lnorm, h₃.Lnorm, h₃.Lnorm ((1 - P) • R • x), sub_smul 1 P, one_smul, smul_sub,
          mul_smul]
      _ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
          (‖R • x - R • P • R • x‖ + ‖((1 - R) * R) • x - (1 - R) • P • R • x‖) := by
        rw [h₃.proj.eq, sub_smul 1 P, one_smul, smul_sub, mul_smul]
      _ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
          (‖R • x - R • P • R • x‖ + ‖(1 - R) • P • R • x‖) := by
        rw [sub_mul, h₃.proj.eq, one_mul, sub_self, zero_smul, zero_sub, norm_neg]
      _ = ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖ := by abel
      _ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ := by
        rw [GE.ge]
        have :=
          add_le_add_right (norm_le_insert' (R • x) (R • P • R • x)) (2 • ‖(1 - R) • P • R • x‖)
        simpa only [mul_smul, sub_smul, one_smul] using this
  rw [GE.ge] at e1
  nth_rewrite 2 [← add_zero ‖R • x‖]  at e1
  rw [add_le_add_iff_left, two_smul, ← two_mul] at e1
  rw [le_antisymm_iff]
  refine' ⟨_, norm_nonneg _⟩
  rwa [← MulZeroClass.mul_zero (2 : ℝ), mul_le_mul_left (show (0 : ℝ) < 2 by norm_num)] at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
⊢ P * R = R * P * R

tactic: rw [← norm_sub_eq_zero_iff]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ (P * R) • x = (R * P * R) • x

tactic: have e1 : ‖R • x‖ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ :=
  calc
    ‖R • x‖ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
        (‖(R * R) • x - R • P • R • x‖ + ‖(1 - R) • (1 - P) • R • x‖) := by
      rw [h₁.Lnorm, h₃.Lnorm, h₃.Lnorm ((1 - P) • R • x), sub_smul 1 P, one_smul, smul_sub,
        mul_smul]
    _ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
        (‖R • x - R • P • R • x‖ + ‖((1 - R) * R) • x - (1 - R) • P • R • x‖) := by
      rw [h₃.proj.eq, sub_smul 1 P, one_smul, smul_sub, mul_smul]
    _ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ +
        (‖R • x - R • P • R • x‖ + ‖(1 - R) • P • R • x‖) := by
      rw [sub_mul, h₃.proj.eq, one_mul, sub_self, zero_smul, zero_sub, norm_neg]
    _ = ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖ := by abel
    _ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ := by
      rw [GE.ge]
      have :=
        add_le_add_right (norm_le_insert' (R • x) (R • P • R • x)) (2 • ‖(1 - R) • P • R • x‖)
      simpa only [mul_smul, sub_smul, one_smul] using this
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ ‖(P * R) • x - (R * P * R) • x‖ = 0

tactic: rw [GE.ge] at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
e1 : ‖R • x‖ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖
⊢ ‖(P * R) • x - (R * P * R) • x‖ = 0

tactic: nth_rewrite 2 [← add_zero ‖R • x‖]  at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
e1 : ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ ≤ ‖R • x‖
⊢ ‖(P * R) • x - (R * P * R) • x‖ = 0

tactic: rw [add_le_add_iff_left, two_smul, ← two_mul] at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
e1 : ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ ≤ ‖R • x‖ + 0
⊢ ‖(P * R) • x - (R * P * R) • x‖ = 0

tactic: rw [le_antisymm_iff]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
e1 : 2 * ‖(P * R) • x - (R * P * R) • x‖ ≤ 0
⊢ ‖(P * R) • x - (R * P * R) • x‖ = 0

tactic: refine' ⟨_, norm_nonneg _⟩
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
e1 : 2 * ‖(P * R) • x - (R * P * R) • x‖ ≤ 0
⊢ ‖(P * R) • x - (R * P * R) • x‖ ≤ 0 ∧ 0 ≤ ‖(P * R) • x - (R * P * R) • x‖

tactic: rwa [← MulZeroClass.mul_zero (2 : ℝ), mul_le_mul_left (show (0 : ℝ) < 2 by norm_num)] at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
e1 : 2 * ‖(P * R) • x - (R * P * R) • x‖ ≤ 0
⊢ ‖(P * R) • x - (R * P * R) • x‖ ≤ 0

tactic: rw [h₁.Lnorm, h₃.Lnorm, h₃.Lnorm ((1 - P) • R • x), sub_smul 1 P, one_smul, smul_sub,
  mul_smul]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ ‖R • x‖ = ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ + (‖(R * R) • x - R • P • R • x‖ + ‖(1 - R) • (1 - P) • R • x‖)

tactic: rw [h₃.proj.eq, sub_smul 1 P, one_smul, smul_sub, mul_smul]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ + (‖(R * R) • x - R • P • R • x‖ + ‖(1 - R) • (1 - P) • R • x‖) =
    ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ + (‖R • x - R • P • R • x‖ + ‖((1 - R) * R) • x - (1 - R) • P • R • x‖)

tactic: rw [sub_mul, h₃.proj.eq, one_mul, sub_self, zero_smul, zero_sub, norm_neg]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ + (‖R • x - R • P • R • x‖ + ‖((1 - R) * R) • x - (1 - R) • P • R • x‖) =
    ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ + (‖R • x - R • P • R • x‖ + ‖(1 - R) • P • R • x‖)

tactic: abel
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ ‖R • P • R • x‖ + ‖(1 - R) • P • R • x‖ + (‖R • x - R • P • R • x‖ + ‖(1 - R) • P • R • x‖) =
    ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖

tactic: rw [GE.ge]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖ ≥ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖

tactic: have :=
  add_le_add_right (norm_le_insert' (R • x) (R • P • R • x)) (2 • ‖(1 - R) • P • R • x‖)
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
⊢ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ ≤ ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖

tactic: simpa only [mul_smul, sub_smul, one_smul] using this
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
this : ‖R • x‖ + 2 • ‖(1 - R) • P • R • x‖ ≤ ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖
⊢ ‖R • x‖ + 2 • ‖(P * R) • x - (R * P * R) • x‖ ≤ ‖R • P • R • x‖ + ‖R • x - R • P • R • x‖ + 2 • ‖(1 - R) • P • R • x‖

tactic: norm_num
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
R : M
h₃ : IsLprojection X R
x : X
e1 : 2 * ‖(P * R) • x - (R * P * R) • x‖ ≤ 2 * 0
⊢ 0 < 2

tactic: have e1 : P * (1 - Q) = P * (1 - Q) - (Q * P - Q * P * Q) :=
  calc
    P * (1 - Q) = (1 - Q) * P * (1 - Q) := by rw [PR_eq_RPR (1 - Q) h₂.Lcomplement]
    _ = P * (1 - Q) - (Q * P - Q * P * Q) := by noncomm_ring
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
PR_eq_RPR : ∀ (R : M), IsLprojection X R → P * R = R * P * R
⊢ Q * P = Q * P * Q

tactic: rwa [eq_sub_iff_add_eq, add_right_eq_self, sub_eq_zero] at e1
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
PR_eq_RPR : ∀ (R : M), IsLprojection X R → P * R = R * P * R
e1 : P * (1 - Q) = P * (1 - Q) - (Q * P - Q * P * Q)
⊢ Q * P = Q * P * Q

tactic: rw [PR_eq_RPR (1 - Q) h₂.Lcomplement]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
PR_eq_RPR : ∀ (R : M), IsLprojection X R → P * R = R * P * R
⊢ P * (1 - Q) = (1 - Q) * P * (1 - Q)

tactic: noncomm_ring
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
PR_eq_RPR : ∀ (R : M), IsLprojection X R → P * R = R * P * R
⊢ (1 - Q) * P * (1 - Q) = P * (1 - Q) - (Q * P - Q * P * Q)

tactic: rw [QP_eq_QPQ, PR_eq_RPR Q h₂]
state_before: X : Type u_2
inst✝³ : NormedAddCommGroup X
M : Type u_1
inst✝² : Ring M
inst✝¹ : Module M X
inst✝ : FaithfulSMul M X
P Q : M
h₁ : IsLprojection X P
h₂ : IsLprojection X Q
PR_eq_RPR : ∀ (R : M), IsLprojection X R → P * R = R * P * R
QP_eq_QPQ : Q * P = Q * P * Q
⊢ P * Q = Q * P