l3lab/ntp-mathlib huggingface dataset:
@[simp]
lemma sq_sqrt : hA.sqrt ^ 2 = A := by
  let C := hA.1.eigenvectorMatrix
  let E := diagonal ((↑) ∘ Real.sqrt ∘ hA.1.eigenvalues : n → 𝕜)
  suffices : C * (E * (Cᴴ * C) * E) * Cᴴ = A
  · rw [Matrix.PosSemidef.sqrt, pow_two]
    change (C * E * Cᴴ) * (C * E * Cᴴ) = A
    simpa only [← mul_assoc] using this
  have : Cᴴ * C = 1
  · rw [Matrix.IsHermitian.conjTranspose_eigenvectorMatrix, mul_eq_one_comm]
    exact hA.1.eigenvectorMatrix_mul_inv
  rw [this, mul_one]
  have : E * E = diagonal ((↑) ∘ hA.1.eigenvalues)
  · rw [diagonal_mul_diagonal]
    

Proof state:
case this
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
C : Matrix n n 𝕜 := IsHermitian.eigenvectorMatrix (_ : IsHermitian A)
E : Matrix n n 𝕜 := diagonal (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
this : Cᴴ * C = 1
⊢ (diagonal fun i =>
      (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A)) i *
        (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A)) i) =
    diagonal (IsROrC.ofReal ∘ IsHermitian.eigenvalues (_ : IsHermitian A))

Next tactic:
refine congr_arg _ (funext fun v ↦ ?_)
@[simp]
lemma sq_sqrt : hA.sqrt ^ 2 = A := by
  let C := hA.1.eigenvectorMatrix
  let E := diagonal ((↑) ∘ Real.sqrt ∘ hA.1.eigenvalues : n → 𝕜)
  suffices : C * (E * (Cᴴ * C) * E) * Cᴴ = A
  · rw [Matrix.PosSemidef.sqrt, pow_two]
    change (C * E * Cᴴ) * (C * E * Cᴴ) = A
    simpa only [← mul_assoc] using this
  have : Cᴴ * C = 1
  · rw [Matrix.IsHermitian.conjTranspose_eigenvectorMatrix, mul_eq_one_comm]
    exact hA.1.eigenvectorMatrix_mul_inv
  rw [this, mul_one]
  have : E * E = diagonal ((↑) ∘ hA.1.eigenvalues)
  · rw [diagonal_mul_diagonal]
    refine congr_arg _ (funext fun v ↦ ?_) -- why doesn't "congr with v" work?
    

Proof state:
case this
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
C : Matrix n n 𝕜 := IsHermitian.eigenvectorMatrix (_ : IsHermitian A)
E : Matrix n n 𝕜 := diagonal (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
this : Cᴴ * C = 1
v : n
⊢ (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A)) v *
      (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A)) v =
    (IsROrC.ofReal ∘ IsHermitian.eigenvalues (_ : IsHermitian A)) v

Next tactic:
simp [← pow_two, ← IsROrC.ofReal_pow, Real.sq_sqrt (hA.eigenvalues_nonneg v)]
@[simp]
lemma sq_sqrt : hA.sqrt ^ 2 = A := by
  let C := hA.1.eigenvectorMatrix
  let E := diagonal ((↑) ∘ Real.sqrt ∘ hA.1.eigenvalues : n → 𝕜)
  suffices : C * (E * (Cᴴ * C) * E) * Cᴴ = A
  · rw [Matrix.PosSemidef.sqrt, pow_two]
    change (C * E * Cᴴ) * (C * E * Cᴴ) = A
    simpa only [← mul_assoc] using this
  have : Cᴴ * C = 1
  · rw [Matrix.IsHermitian.conjTranspose_eigenvectorMatrix, mul_eq_one_comm]
    exact hA.1.eigenvectorMatrix_mul_inv
  rw [this, mul_one]
  have : E * E = diagonal ((↑) ∘ hA.1.eigenvalues)
  · rw [diagonal_mul_diagonal]
    refine congr_arg _ (funext fun v ↦ ?_) -- why doesn't "congr with v" work?
    simp [← pow_two, ← IsROrC.ofReal_pow, Real.sq_sqrt (hA.eigenvalues_nonneg v)]
  

Proof state:
case this
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
C : Matrix n n 𝕜 := IsHermitian.eigenvectorMatrix (_ : IsHermitian A)
E : Matrix n n 𝕜 := diagonal (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
this✝ : Cᴴ * C = 1
this : E * E = diagonal (IsROrC.ofReal ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
⊢ C * (E * E) * Cᴴ = A

Next tactic:
rw [this]
@[simp]
lemma sq_sqrt : hA.sqrt ^ 2 = A := by
  let C := hA.1.eigenvectorMatrix
  let E := diagonal ((↑) ∘ Real.sqrt ∘ hA.1.eigenvalues : n → 𝕜)
  suffices : C * (E * (Cᴴ * C) * E) * Cᴴ = A
  · rw [Matrix.PosSemidef.sqrt, pow_two]
    change (C * E * Cᴴ) * (C * E * Cᴴ) = A
    simpa only [← mul_assoc] using this
  have : Cᴴ * C = 1
  · rw [Matrix.IsHermitian.conjTranspose_eigenvectorMatrix, mul_eq_one_comm]
    exact hA.1.eigenvectorMatrix_mul_inv
  rw [this, mul_one]
  have : E * E = diagonal ((↑) ∘ hA.1.eigenvalues)
  · rw [diagonal_mul_diagonal]
    refine congr_arg _ (funext fun v ↦ ?_) -- why doesn't "congr with v" work?
    simp [← pow_two, ← IsROrC.ofReal_pow, Real.sq_sqrt (hA.eigenvalues_nonneg v)]
  rw [this]
  

Proof state:
case this
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
C : Matrix n n 𝕜 := IsHermitian.eigenvectorMatrix (_ : IsHermitian A)
E : Matrix n n 𝕜 := diagonal (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
this✝ : Cᴴ * C = 1
this : E * E = diagonal (IsROrC.ofReal ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
⊢ C * diagonal (IsROrC.ofReal ∘ IsHermitian.eigenvalues (_ : IsHermitian A)) * Cᴴ = A

Next tactic:
convert hA.1.spectral_theorem'.symm
@[simp]
lemma sq_sqrt : hA.sqrt ^ 2 = A := by
  let C := hA.1.eigenvectorMatrix
  let E := diagonal ((↑) ∘ Real.sqrt ∘ hA.1.eigenvalues : n → 𝕜)
  suffices : C * (E * (Cᴴ * C) * E) * Cᴴ = A
  · rw [Matrix.PosSemidef.sqrt, pow_two]
    change (C * E * Cᴴ) * (C * E * Cᴴ) = A
    simpa only [← mul_assoc] using this
  have : Cᴴ * C = 1
  · rw [Matrix.IsHermitian.conjTranspose_eigenvectorMatrix, mul_eq_one_comm]
    exact hA.1.eigenvectorMatrix_mul_inv
  rw [this, mul_one]
  have : E * E = diagonal ((↑) ∘ hA.1.eigenvalues)
  · rw [diagonal_mul_diagonal]
    refine congr_arg _ (funext fun v ↦ ?_) -- why doesn't "congr with v" work?
    simp [← pow_two, ← IsROrC.ofReal_pow, Real.sq_sqrt (hA.eigenvalues_nonneg v)]
  rw [this]
  convert hA.1.spectral_theorem'.symm
  

Proof state:
case h.e'_2.h.e'_6
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
C : Matrix n n 𝕜 := IsHermitian.eigenvectorMatrix (_ : IsHermitian A)
E : Matrix n n 𝕜 := diagonal (IsROrC.ofReal ∘ Real.sqrt ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
this✝ : Cᴴ * C = 1
this : E * E = diagonal (IsROrC.ofReal ∘ IsHermitian.eigenvalues (_ : IsHermitian A))
⊢ Cᴴ = IsHermitian.eigenvectorMatrixInv (_ : IsHermitian A)

Next tactic:
apply Matrix.IsHermitian.conjTranspose_eigenvectorMatrix
@[simp]
lemma sqrt_mul_self : hA.sqrt * hA.sqrt = A := by 

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
⊢ hA.sqrt * hA.sqrt = A

Next tactic:
rw [← pow_two, sq_sqrt]
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
⊢ A = B

Next tactic:
by_contra h_ne
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
⊢ False

Next tactic:
let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
⊢ False

Next tactic:
have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · 

Proof state:
case h_sum
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
⊢ 0 = ↑t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)

Next tactic:
calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
      _ = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v) := by
        simp_rw [← star_mulVec, hv', mul_add, ← IsROrC.real_smul_eq_coe_mul, ← smul_dotProduct]
        congr 2 with i
        simp only [Pi.star_apply, Pi.smul_apply, IsROrC.real_smul_eq_coe_mul, star_mul',
          IsROrC.star_def, IsROrC.conj_ofReal]
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by 

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
⊢ 0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v

Next tactic:
rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
⊢ star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v = star v ⬝ᵥ mulVec A (mulVec (A - B) v) + star v ⬝ᵥ mulVec (A - B) (mulVec B v)

Next tactic:
rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
⊢ star v ⬝ᵥ mulVec A (mulVec (A - B) v) + star v ⬝ᵥ mulVec (A - B) (mulVec B v) =
    ↑t * star v ⬝ᵥ mulVec A v + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v

Next tactic:
rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
      _ = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v) := by
        

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
⊢ ↑t * star v ⬝ᵥ mulVec A v + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v =
    ↑t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)

Next tactic:
simp_rw [← star_mulVec, hv', mul_add, ← IsROrC.real_smul_eq_coe_mul, ← smul_dotProduct]
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
      _ = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v) := by
        simp_rw [← star_mulVec, hv', mul_add, ← IsROrC.real_smul_eq_coe_mul, ← smul_dotProduct]
        

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
⊢ t • star v ⬝ᵥ mulVec A v + star (t • v) ⬝ᵥ mulVec B v = t • star v ⬝ᵥ mulVec A v + t • star v ⬝ᵥ mulVec B v

Next tactic:
congr 2 with i
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
      _ = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v) := by
        simp_rw [← star_mulVec, hv', mul_add, ← IsROrC.real_smul_eq_coe_mul, ← smul_dotProduct]
        congr 2 with i
        

Proof state:
case e_a.e_v.h
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
i : n
⊢ star (t • v) i = (t • star v) i

Next tactic:
simp only [Pi.star_apply, Pi.smul_apply, IsROrC.real_smul_eq_coe_mul, star_mul',
          IsROrC.star_def, IsROrC.conj_ofReal]