l3lab/ntp-mathlib huggingface dataset:
/-- The inverse isometric equivalence of an isometric equivalence between two quadratic forms. -/
@[symm]
def symm (f : Q₁.IsometryEquiv Q₂) : Q₂.IsometryEquiv Q₁ :=
  { (f : M₁ ≃ₗ[R] M₂).symm with
    map_app' := by intro m; 

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M
inst✝⁶ : AddCommMonoid M₁
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : AddCommMonoid M₃
inst✝³ : Module R M
inst✝² : Module R M₁
inst✝¹ : Module R M₂
inst✝ : Module R M₃
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
Q₃ : QuadraticForm R M₃
f : IsometryEquiv Q₁ Q₂
src✝ : M₂ ≃ₗ[R] M₁ := LinearEquiv.symm f.toLinearEquiv
m : M₂
⊢ Q₁
      (AddHom.toFun
        (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
              right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
        m) =
    Q₂ m

Next tactic:
rw [← f.map_app]
/-- The inverse isometric equivalence of an isometric equivalence between two quadratic forms. -/
@[symm]
def symm (f : Q₁.IsometryEquiv Q₂) : Q₂.IsometryEquiv Q₁ :=
  { (f : M₁ ≃ₗ[R] M₂).symm with
    map_app' := by intro m; rw [← f.map_app]; 

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M
inst✝⁶ : AddCommMonoid M₁
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : AddCommMonoid M₃
inst✝³ : Module R M
inst✝² : Module R M₁
inst✝¹ : Module R M₂
inst✝ : Module R M₃
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
Q₃ : QuadraticForm R M₃
f : IsometryEquiv Q₁ Q₂
src✝ : M₂ ≃ₗ[R] M₁ := LinearEquiv.symm f.toLinearEquiv
m : M₂
⊢ Q₂
      (f
        (AddHom.toFun
          (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun,
                left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
                right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
          m)) =
    Q₂ m

Next tactic:
congr
/-- The inverse isometric equivalence of an isometric equivalence between two quadratic forms. -/
@[symm]
def symm (f : Q₁.IsometryEquiv Q₂) : Q₂.IsometryEquiv Q₁ :=
  { (f : M₁ ≃ₗ[R] M₂).symm with
    map_app' := by intro m; rw [← f.map_app]; congr; 

Proof state:
case h.e_6.h
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M
inst✝⁶ : AddCommMonoid M₁
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : AddCommMonoid M₃
inst✝³ : Module R M
inst✝² : Module R M₁
inst✝¹ : Module R M₂
inst✝ : Module R M₃
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
Q₃ : QuadraticForm R M₃
f : IsometryEquiv Q₁ Q₂
src✝ : M₂ ≃ₗ[R] M₁ := LinearEquiv.symm f.toLinearEquiv
m : M₂
⊢ f
      (AddHom.toFun
        (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
              right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
        m) =
    m

Next tactic:
exact f.toLinearEquiv.apply_symm_apply m
/-- The composition of two isometric equivalences between quadratic forms. -/
@[trans]
def trans (f : Q₁.IsometryEquiv Q₂) (g : Q₂.IsometryEquiv Q₃) : Q₁.IsometryEquiv Q₃ :=
  { (f : M₁ ≃ₗ[R] M₂).trans (g : M₂ ≃ₗ[R] M₃) with
    map_app' := by 

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M
inst✝⁶ : AddCommMonoid M₁
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : AddCommMonoid M₃
inst✝³ : Module R M
inst✝² : Module R M₁
inst✝¹ : Module R M₂
inst✝ : Module R M₃
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
Q₃ : QuadraticForm R M₃
f : IsometryEquiv Q₁ Q₂
g : IsometryEquiv Q₂ Q₃
src✝ : M₁ ≃ₗ[R] M₃ := f.toLinearEquiv ≪≫ₗ g.toLinearEquiv
⊢ ∀ (m : M₁),
    Q₃
        (AddHom.toFun
          (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun,
                left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
                right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
          m) =
      Q₁ m

Next tactic:
intro m
/-- The composition of two isometric equivalences between quadratic forms. -/
@[trans]
def trans (f : Q₁.IsometryEquiv Q₂) (g : Q₂.IsometryEquiv Q₃) : Q₁.IsometryEquiv Q₃ :=
  { (f : M₁ ≃ₗ[R] M₂).trans (g : M₂ ≃ₗ[R] M₃) with
    map_app' := by intro m; 

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M
inst✝⁶ : AddCommMonoid M₁
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : AddCommMonoid M₃
inst✝³ : Module R M
inst✝² : Module R M₁
inst✝¹ : Module R M₂
inst✝ : Module R M₃
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
Q₃ : QuadraticForm R M₃
f : IsometryEquiv Q₁ Q₂
g : IsometryEquiv Q₂ Q₃
src✝ : M₁ ≃ₗ[R] M₃ := f.toLinearEquiv ≪≫ₗ g.toLinearEquiv
m : M₁
⊢ Q₃
      (AddHom.toFun
        (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
              right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
        m) =
    Q₁ m

Next tactic:
rw [← f.map_app, ← g.map_app]
/-- The composition of two isometric equivalences between quadratic forms. -/
@[trans]
def trans (f : Q₁.IsometryEquiv Q₂) (g : Q₂.IsometryEquiv Q₃) : Q₁.IsometryEquiv Q₃ :=
  { (f : M₁ ≃ₗ[R] M₂).trans (g : M₂ ≃ₗ[R] M₃) with
    map_app' := by intro m; rw [← f.map_app, ← g.map_app]; 

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M
inst✝⁶ : AddCommMonoid M₁
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : AddCommMonoid M₃
inst✝³ : Module R M
inst✝² : Module R M₁
inst✝¹ : Module R M₂
inst✝ : Module R M₃
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
Q₃ : QuadraticForm R M₃
f : IsometryEquiv Q₁ Q₂
g : IsometryEquiv Q₂ Q₃
src✝ : M₁ ≃ₗ[R] M₃ := f.toLinearEquiv ≪≫ₗ g.toLinearEquiv
m : M₁
⊢ Q₃
      (AddHom.toFun
        (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
              right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
        m) =
    Q₃ (g (f m))

Next tactic:
rfl
/-- A quadratic form composed with a `LinearEquiv` is isometric to itself. -/
def isometryEquivOfCompLinearEquiv (Q : QuadraticForm R M) (f : M₁ ≃ₗ[R] M) :
    Q.IsometryEquiv (Q.comp (f : M₁ →ₗ[R] M)) :=
  { f.symm with
    map_app' := by
      

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁹ : CommSemiring R
inst✝⁸ : AddCommMonoid M
inst✝⁷ : AddCommMonoid M₁
inst✝⁶ : AddCommMonoid M₂
inst✝⁵ : AddCommMonoid M₃
inst✝⁴ : Module R M
inst✝³ : Module R M₁
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Fintype ι
v : Basis ι R M
Q : QuadraticForm R M
f : M₁ ≃ₗ[R] M
src✝ : M ≃ₗ[R] M₁ := LinearEquiv.symm f
⊢ ∀ (m : M),
    (comp Q ↑f)
        (AddHom.toFun
          (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun,
                left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
                right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
          m) =
      Q m

Next tactic:
intro
/-- A quadratic form composed with a `LinearEquiv` is isometric to itself. -/
def isometryEquivOfCompLinearEquiv (Q : QuadraticForm R M) (f : M₁ ≃ₗ[R] M) :
    Q.IsometryEquiv (Q.comp (f : M₁ →ₗ[R] M)) :=
  { f.symm with
    map_app' := by
      intro
      

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝⁹ : CommSemiring R
inst✝⁸ : AddCommMonoid M
inst✝⁷ : AddCommMonoid M₁
inst✝⁶ : AddCommMonoid M₂
inst✝⁵ : AddCommMonoid M₃
inst✝⁴ : Module R M
inst✝³ : Module R M₁
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Fintype ι
v : Basis ι R M
Q : QuadraticForm R M
f : M₁ ≃ₗ[R] M
src✝ : M ≃ₗ[R] M₁ := LinearEquiv.symm f
m✝ : M
⊢ (comp Q ↑f)
      (AddHom.toFun
        (↑{ toLinearMap := ↑src✝, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
              right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }).toAddHom
        m✝) =
    Q m✝

Next tactic:
simp only [comp_apply, LinearEquiv.coe_coe, LinearEquiv.toFun_eq_coe,
        LinearEquiv.apply_symm_apply, f.apply_symm_apply]
/-- Given an orthogonal basis, a quadratic form is isometrically equivalent with a weighted sum of
squares. -/
noncomputable def isometryEquivWeightedSumSquares (Q : QuadraticForm K V)
    (v : Basis (Fin (FiniteDimensional.finrank K V)) K V)
    (hv₁ : (associated (R := K) Q).iIsOrtho v) :
    Q.IsometryEquiv (weightedSumSquares K fun i => Q (v i)) := by
  

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹³ : CommSemiring R
inst✝¹² : AddCommMonoid M
inst✝¹¹ : AddCommMonoid M₁
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : Module R M
inst✝⁷ : Module R M₁
inst✝⁶ : Module R M₂
inst✝⁵ : Module R M₃
inst✝⁴ : Fintype ι
v✝ : Basis ι R M
inst✝³ : Field K
inst✝² : Invertible 2
inst✝¹ : AddCommGroup V
inst✝ : Module K V
Q : QuadraticForm K V
v : Basis (Fin (FiniteDimensional.finrank K V)) K V
hv₁ : BilinForm.iIsOrtho (associated Q) ⇑v
⊢ IsometryEquiv Q (weightedSumSquares K fun i => Q (v i))

Next tactic:
let iso := Q.isometryEquivBasisRepr v
/-- Given an orthogonal basis, a quadratic form is isometrically equivalent with a weighted sum of
squares. -/
noncomputable def isometryEquivWeightedSumSquares (Q : QuadraticForm K V)
    (v : Basis (Fin (FiniteDimensional.finrank K V)) K V)
    (hv₁ : (associated (R := K) Q).iIsOrtho v) :
    Q.IsometryEquiv (weightedSumSquares K fun i => Q (v i)) := by
  let iso := Q.isometryEquivBasisRepr v
  

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹³ : CommSemiring R
inst✝¹² : AddCommMonoid M
inst✝¹¹ : AddCommMonoid M₁
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : Module R M
inst✝⁷ : Module R M₁
inst✝⁶ : Module R M₂
inst✝⁵ : Module R M₃
inst✝⁴ : Fintype ι
v✝ : Basis ι R M
inst✝³ : Field K
inst✝² : Invertible 2
inst✝¹ : AddCommGroup V
inst✝ : Module K V
Q : QuadraticForm K V
v : Basis (Fin (FiniteDimensional.finrank K V)) K V
hv₁ : BilinForm.iIsOrtho (associated Q) ⇑v
iso : IsometryEquiv Q (basisRepr Q v) := isometryEquivBasisRepr Q v
⊢ IsometryEquiv Q (weightedSumSquares K fun i => Q (v i))

Next tactic:
refine' ⟨iso, fun m => _⟩
/-- Given an orthogonal basis, a quadratic form is isometrically equivalent with a weighted sum of
squares. -/
noncomputable def isometryEquivWeightedSumSquares (Q : QuadraticForm K V)
    (v : Basis (Fin (FiniteDimensional.finrank K V)) K V)
    (hv₁ : (associated (R := K) Q).iIsOrtho v) :
    Q.IsometryEquiv (weightedSumSquares K fun i => Q (v i)) := by
  let iso := Q.isometryEquivBasisRepr v
  refine' ⟨iso, fun m => _⟩
  

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹³ : CommSemiring R
inst✝¹² : AddCommMonoid M
inst✝¹¹ : AddCommMonoid M₁
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : Module R M
inst✝⁷ : Module R M₁
inst✝⁶ : Module R M₂
inst✝⁵ : Module R M₃
inst✝⁴ : Fintype ι
v✝ : Basis ι R M
inst✝³ : Field K
inst✝² : Invertible 2
inst✝¹ : AddCommGroup V
inst✝ : Module K V
Q : QuadraticForm K V
v : Basis (Fin (FiniteDimensional.finrank K V)) K V
hv₁ : BilinForm.iIsOrtho (associated Q) ⇑v
iso : IsometryEquiv Q (basisRepr Q v) := isometryEquivBasisRepr Q v
m : V
⊢ (weightedSumSquares K fun i => Q (v i)) (AddHom.toFun iso.toAddHom m) = Q m

Next tactic:
convert iso.map_app m
/-- Given an orthogonal basis, a quadratic form is isometrically equivalent with a weighted sum of
squares. -/
noncomputable def isometryEquivWeightedSumSquares (Q : QuadraticForm K V)
    (v : Basis (Fin (FiniteDimensional.finrank K V)) K V)
    (hv₁ : (associated (R := K) Q).iIsOrtho v) :
    Q.IsometryEquiv (weightedSumSquares K fun i => Q (v i)) := by
  let iso := Q.isometryEquivBasisRepr v
  refine' ⟨iso, fun m => _⟩
  convert iso.map_app m
  

Proof state:
case h.e'_2.h.e'_5
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹³ : CommSemiring R
inst✝¹² : AddCommMonoid M
inst✝¹¹ : AddCommMonoid M₁
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : Module R M
inst✝⁷ : Module R M₁
inst✝⁶ : Module R M₂
inst✝⁵ : Module R M₃
inst✝⁴ : Fintype ι
v✝ : Basis ι R M
inst✝³ : Field K
inst✝² : Invertible 2
inst✝¹ : AddCommGroup V
inst✝ : Module K V
Q : QuadraticForm K V
v : Basis (Fin (FiniteDimensional.finrank K V)) K V
hv₁ : BilinForm.iIsOrtho (associated Q) ⇑v
iso : IsometryEquiv Q (basisRepr Q v) := isometryEquivBasisRepr Q v
m : V
⊢ (weightedSumSquares K fun i => Q (v i)) = basisRepr Q v

Next tactic:
rw [basisRepr_eq_of_iIsOrtho _ _ hv₁]
theorem equivalent_weightedSumSquares_units_of_nondegenerate' (Q : QuadraticForm K V)
    (hQ : (associated (R := K) Q).Nondegenerate) :
    ∃ w : Fin (FiniteDimensional.finrank K V) → Kˣ, Equivalent Q (weightedSumSquares K w) := by
  

Proof state:
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹⁴ : CommSemiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : AddCommMonoid M₁
inst✝¹¹ : AddCommMonoid M₂
inst✝¹⁰ : AddCommMonoid M₃
inst✝⁹ : Module R M
inst✝⁸ : Module R M₁
inst✝⁷ : Module R M₂
inst✝⁶ : Module R M₃
inst✝⁵ : Fintype ι
v : Basis ι R M
inst✝⁴ : Field K
inst✝³ : Invertible 2
inst✝² : AddCommGroup V
inst✝¹ : Module K V
inst✝ : FiniteDimensional K V
Q : QuadraticForm K V
hQ : Nondegenerate (associated Q)
⊢ ∃ w, Equivalent Q (weightedSumSquares K w)

Next tactic:
obtain ⟨v, hv₁⟩ := exists_orthogonal_basis (associated_isSymm K Q)
theorem equivalent_weightedSumSquares_units_of_nondegenerate' (Q : QuadraticForm K V)
    (hQ : (associated (R := K) Q).Nondegenerate) :
    ∃ w : Fin (FiniteDimensional.finrank K V) → Kˣ, Equivalent Q (weightedSumSquares K w) := by
  obtain ⟨v, hv₁⟩ := exists_orthogonal_basis (associated_isSymm K Q)
  

Proof state:
case intro
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹⁴ : CommSemiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : AddCommMonoid M₁
inst✝¹¹ : AddCommMonoid M₂
inst✝¹⁰ : AddCommMonoid M₃
inst✝⁹ : Module R M
inst✝⁸ : Module R M₁
inst✝⁷ : Module R M₂
inst✝⁶ : Module R M₃
inst✝⁵ : Fintype ι
v✝ : Basis ι R M
inst✝⁴ : Field K
inst✝³ : Invertible 2
inst✝² : AddCommGroup V
inst✝¹ : Module K V
inst✝ : FiniteDimensional K V
Q : QuadraticForm K V
hQ : Nondegenerate (associated Q)
v : Basis (Fin (FiniteDimensional.finrank K V)) K V
hv₁ : iIsOrtho ((associatedHom K) Q) ⇑v
⊢ ∃ w, Equivalent Q (weightedSumSquares K w)

Next tactic:
have hv₂ := hv₁.not_isOrtho_basis_self_of_nondegenerate hQ
theorem equivalent_weightedSumSquares_units_of_nondegenerate' (Q : QuadraticForm K V)
    (hQ : (associated (R := K) Q).Nondegenerate) :
    ∃ w : Fin (FiniteDimensional.finrank K V) → Kˣ, Equivalent Q (weightedSumSquares K w) := by
  obtain ⟨v, hv₁⟩ := exists_orthogonal_basis (associated_isSymm K Q)
  have hv₂ := hv₁.not_isOrtho_basis_self_of_nondegenerate hQ
  

Proof state:
case intro
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹⁴ : CommSemiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : AddCommMonoid M₁
inst✝¹¹ : AddCommMonoid M₂
inst✝¹⁰ : AddCommMonoid M₃
inst✝⁹ : Module R M
inst✝⁸ : Module R M₁
inst✝⁷ : Module R M₂
inst✝⁶ : Module R M₃
inst✝⁵ : Fintype ι
v✝ : Basis ι R M
inst✝⁴ : Field K
inst✝³ : Invertible 2
inst✝² : AddCommGroup V
inst✝¹ : Module K V
inst✝ : FiniteDimensional K V
Q : QuadraticForm K V
hQ : Nondegenerate (associated Q)
v : Basis (Fin (FiniteDimensional.finrank K V)) K V
hv₁ : iIsOrtho ((associatedHom K) Q) ⇑v
hv₂ : ∀ (i : Fin (FiniteDimensional.finrank K V)), ¬IsOrtho ((associatedHom K) Q) (v i) (v i)
⊢ ∃ w, Equivalent Q (weightedSumSquares K w)

Next tactic:
simp_rw [IsOrtho, associated_eq_self_apply] at hv₂
theorem equivalent_weightedSumSquares_units_of_nondegenerate' (Q : QuadraticForm K V)
    (hQ : (associated (R := K) Q).Nondegenerate) :
    ∃ w : Fin (FiniteDimensional.finrank K V) → Kˣ, Equivalent Q (weightedSumSquares K w) := by
  obtain ⟨v, hv₁⟩ := exists_orthogonal_basis (associated_isSymm K Q)
  have hv₂ := hv₁.not_isOrtho_basis_self_of_nondegenerate hQ
  simp_rw [IsOrtho, associated_eq_self_apply] at hv₂
  

Proof state:
case intro
ι : Type u_1
R : Type u_2
K : Type u_3
M : Type u_4
M₁ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
V : Type u_8
inst✝¹⁴ : CommSemiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : AddCommMonoid M₁
inst✝¹¹ : AddCommMonoid M₂
inst✝¹⁰ : AddCommMonoid M₃
inst✝⁹ : Module R M
inst✝⁸ : Module R M₁
inst✝⁷ : Module R M₂
inst✝⁶ : Module R M₃
inst✝⁵ : Fintype ι
v✝ : Basis ι R M
inst✝⁴ : Field K
inst✝³ : Invertible 2
inst✝² : AddCommGroup V
inst✝¹ : Module K V
inst✝ : FiniteDimensional K V
Q : QuadraticForm K V
hQ : Nondegenerate (associated Q)
v : Basis (Fin (FiniteDimensional.finrank K V)) K V
hv₁ : iIsOrtho ((associatedHom K) Q) ⇑v
hv₂ : ∀ (i : Fin (FiniteDimensional.finrank K V)), ¬Q (v i) = 0
⊢ ∃ w, Equivalent Q (weightedSumSquares K w)

Next tactic:
exact ⟨fun i => Units.mk0 _ (hv₂ i), ⟨Q.isometryEquivWeightedSumSquares v hv₁⟩⟩
instance : Category.{v₁} (Mat_ C) where
  Hom := Hom
  id := Hom.id
  comp f g := f.comp g
  id_comp f := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ 𝟙 X✝ ≫ f = f

Next tactic:
simp (config := { unfoldPartialApp := true }) [dite_comp]
instance : Category.{v₁} (Mat_ C) where
  Hom := Hom
  id := Hom.id
  comp f g := f.comp g
  id_comp f := by simp (config := { unfoldPartialApp := true }) [dite_comp]
  comp_id f := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ f ≫ 𝟙 Y✝ = f

Next tactic:
simp (config := { unfoldPartialApp := true }) [comp_dite]
instance : Category.{v₁} (Mat_ C) where
  Hom := Hom
  id := Hom.id
  comp f g := f.comp g
  id_comp f := by simp (config := { unfoldPartialApp := true }) [dite_comp]
  comp_id f := by simp (config := { unfoldPartialApp := true }) [comp_dite]
  assoc f g h := by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
W✝ X✝ Y✝ Z✝ : Mat_ C
f : W✝ ⟶ X✝
g : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
⊢ (f ≫ g) ≫ h = f ≫ g ≫ h

Next tactic:
apply DMatrix.ext
instance : Category.{v₁} (Mat_ C) where
  Hom := Hom
  id := Hom.id
  comp f g := f.comp g
  id_comp f := by simp (config := { unfoldPartialApp := true }) [dite_comp]
  comp_id f := by simp (config := { unfoldPartialApp := true }) [comp_dite]
  assoc f g h := by
    apply DMatrix.ext
    

Proof state:
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
W✝ X✝ Y✝ Z✝ : Mat_ C
f : W✝ ⟶ X✝
g : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
⊢ ∀ (i : W✝.ι) (j : Z✝.ι), ((f ≫ g) ≫ h) i j = (f ≫ g ≫ h) i j

Next tactic:
intros
instance : Category.{v₁} (Mat_ C) where
  Hom := Hom
  id := Hom.id
  comp f g := f.comp g
  id_comp f := by simp (config := { unfoldPartialApp := true }) [dite_comp]
  comp_id f := by simp (config := { unfoldPartialApp := true }) [comp_dite]
  assoc f g h := by
    apply DMatrix.ext
    intros
    

Proof state:
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
W✝ X✝ Y✝ Z✝ : Mat_ C
f : W✝ ⟶ X✝
g : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
i✝ : W✝.ι
j✝ : Z✝.ι
⊢ ((f ≫ g) ≫ h) i✝ j✝ = (f ≫ g ≫ h) i✝ j✝

Next tactic:
simp_rw [Hom.comp, sum_comp, comp_sum, Category.assoc]
instance : Category.{v₁} (Mat_ C) where
  Hom := Hom
  id := Hom.id
  comp f g := f.comp g
  id_comp f := by simp (config := { unfoldPartialApp := true }) [dite_comp]
  comp_id f := by simp (config := { unfoldPartialApp := true }) [comp_dite]
  assoc f g h := by
    apply DMatrix.ext
    intros
    simp_rw [Hom.comp, sum_comp, comp_sum, Category.assoc]
    

Proof state:
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
W✝ X✝ Y✝ Z✝ : Mat_ C
f : W✝ ⟶ X✝
g : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
i✝ : W✝.ι
j✝ : Z✝.ι
⊢ ∑ x : Y✝.ι, ∑ x_1 : X✝.ι, f i✝ x_1 ≫ g x_1 x ≫ h x j✝ = ∑ x : X✝.ι, ∑ j : Y✝.ι, f i✝ x ≫ g x j ≫ h j j✝

Next tactic:
rw [Finset.sum_comm]
@[simp]
theorem id_apply_self (M : Mat_ C) (i : M.ι) : (𝟙 M : Hom M M) i i = 𝟙 _ := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i : M.ι
⊢ 𝟙 M i i = 𝟙 (X M i)

Next tactic:
simp [id_apply]
@[simp]
theorem id_apply_of_ne (M : Mat_ C) (i j : M.ι) (h : i ≠ j) : (𝟙 M : Hom M M) i j = 0 := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
h : i ≠ j
⊢ 𝟙 M i j = 0

Next tactic:
simp [id_apply, h]
instance (M N : Mat_ C) : AddCommGroup (M ⟶ N) := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M N : Mat_ C
⊢ AddCommGroup (M ⟶ N)

Next tactic:
change AddCommGroup (DMatrix M.ι N.ι _)
instance (M N : Mat_ C) : AddCommGroup (M ⟶ N) := by
  change AddCommGroup (DMatrix M.ι N.ι _)
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M N : Mat_ C
⊢ AddCommGroup (DMatrix M.ι N.ι fun i j => (fun i j => X M i ⟶ X N j) i j)

Next tactic:
infer_instance
instance : Preadditive (Mat_ C) where
  add_comp M N K f f' g := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M N K : Mat_ C
f f' : M ⟶ N
g : N ⟶ K
⊢ (f + f') ≫ g = f ≫ g + f' ≫ g

Next tactic:
ext
instance : Preadditive (Mat_ C) where
  add_comp M N K f f' g := by ext; 

Proof state:
case H
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M N K : Mat_ C
f f' : M ⟶ N
g : N ⟶ K
i✝ : M.ι
j✝ : K.ι
⊢ ((f + f') ≫ g) i✝ j✝ = (f ≫ g + f' ≫ g) i✝ j✝

Next tactic:
simp [Finset.sum_add_distrib]
instance : Preadditive (Mat_ C) where
  add_comp M N K f f' g := by ext; simp [Finset.sum_add_distrib]
  comp_add M N K f g g' := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M N K : Mat_ C
f : M ⟶ N
g g' : N ⟶ K
⊢ f ≫ (g + g') = f ≫ g + f ≫ g'

Next tactic:
ext
instance : Preadditive (Mat_ C) where
  add_comp M N K f f' g := by ext; simp [Finset.sum_add_distrib]
  comp_add M N K f g g' := by ext; 

Proof state:
case H
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M N K : Mat_ C
f : M ⟶ N
g g' : N ⟶ K
i✝ : M.ι
j✝ : K.ι
⊢ (f ≫ (g + g')) i✝ j✝ = (f ≫ g + f ≫ g') i✝ j✝

Next tactic:
simp [Finset.sum_add_distrib]
/-- We now prove that `Mat_ C` has finite biproducts.

Be warned, however, that `Mat_ C` is not necessarily Krull-Schmidt,
and so the internal indexing of a biproduct may have nothing to do with the external indexing,
even though the construction we give uses a sigma type.
See however `isoBiproductEmbedding`.
-/
instance hasFiniteBiproducts : HasFiniteBiproducts (Mat_ C) where
  out n :=
    { has_biproduct := fun f =>
        hasBiproduct_of_total
          { pt := ⟨Σ j, (f j).ι, fun p => (f p.1).X p.2⟩
            π := fun j x y => by
              

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
n : ℕ
f : Fin n → Mat_ C
j : Fin n
x : (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd).ι
y : (f j).ι
⊢ (fun i j_1 => X (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd) i ⟶ X (f j) j_1) x y

Next tactic:
refine' if h : x.1 = j then _ else 0