[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible (det A)
⊢ ⅟(det A) • adjugate A * A = 1
[PROOFSTEP]
rw [smul_mul_assoc, adjugate_mul, smul_smul, invOf_mul_self, one_smul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible (det A)
⊢ A * ⅟(det A) • adjugate A = 1
[PROOFSTEP]
rw [mul_smul_comm, mul_adjugate, smul_smul, invOf_mul_self, one_smul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : Invertible (det A)
inst✝ : Invertible A
⊢ ⅟A = ⅟(det A) • adjugate A
[PROOFSTEP]
letI := invertibleOfDetInvertible A
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : Invertible (det A)
inst✝ : Invertible A
this : Invertible A := invertibleOfDetInvertible A
⊢ ⅟A = ⅟(det A) • adjugate A
[PROOFSTEP]
convert (rfl : ⅟A = _)
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : B * A = 1
⊢ det B * det A = 1
[PROOFSTEP]
rw [← det_mul, h, det_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : B * A = 1
⊢ det A * det B = 1
[PROOFSTEP]
rw [mul_comm, ← det_mul, h, det_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : A * B = 1
⊢ det B * det A = 1
[PROOFSTEP]
rw [mul_comm, ← det_mul, h, det_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : A * B = 1
⊢ det A * det B = 1
[PROOFSTEP]
rw [← det_mul, h, det_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : Invertible A
inst✝ : Invertible (det A)
⊢ det ⅟A = ⅟(det A)
[PROOFSTEP]
letI := detInvertibleOfInvertible A
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : Invertible A
inst✝ : Invertible (det A)
this : Invertible (det A) := detInvertibleOfInvertible A
⊢ det ⅟A = ⅟(det A)
[PROOFSTEP]
convert (rfl : _ = ⅟A.det)
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
h : A * B = 1
⊢ B * A = 1
[PROOFSTEP]
letI : Invertible B.det := detInvertibleOfLeftInverse _ _ h
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
h : A * B = 1
this : Invertible (det B) := detInvertibleOfLeftInverse B A h
⊢ B * A = 1
[PROOFSTEP]
letI : Invertible B := invertibleOfDetInvertible B
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
h : A * B = 1
this✝ : Invertible (det B) := detInvertibleOfLeftInverse B A h
this : Invertible B := invertibleOfDetInvertible B
⊢ B * A = 1
[PROOFSTEP]
calc
  B * A = B * A * (B * ⅟B) := by rw [mul_invOf_self, Matrix.mul_one]
  _ = B * (A * B * ⅟B) := by simp only [Matrix.mul_assoc]
  _ = B * ⅟B := by rw [h, Matrix.one_mul]
  _ = 1 := mul_invOf_self B
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
h : A * B = 1
this✝ : Invertible (det B) := detInvertibleOfLeftInverse B A h
this : Invertible B := invertibleOfDetInvertible B
⊢ B * A = B * A * (B * ⅟B)
[PROOFSTEP]
rw [mul_invOf_self, Matrix.mul_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
h : A * B = 1
this✝ : Invertible (det B) := detInvertibleOfLeftInverse B A h
this : Invertible B := invertibleOfDetInvertible B
⊢ B * A * (B * ⅟B) = B * (A * B * ⅟B)
[PROOFSTEP]
simp only [Matrix.mul_assoc]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
h : A * B = 1
this✝ : Invertible (det B) := detInvertibleOfLeftInverse B A h
this : Invertible B := invertibleOfDetInvertible B
⊢ B * (A * B * ⅟B) = B * ⅟B
[PROOFSTEP]
rw [h, Matrix.one_mul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
⊢ Invertible (det Aᵀ)
[PROOFSTEP]
simpa using detInvertibleOfInvertible A
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible Aᵀ
⊢ Invertible A
[PROOFSTEP]
rw [← transpose_transpose A]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible Aᵀ
⊢ Invertible Aᵀᵀ
[PROOFSTEP]
infer_instance
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : StarRing α
inst✝ : Invertible Aᴴ
⊢ Invertible A
[PROOFSTEP]
rw [← conjTranspose_conjTranspose A, ← star_eq_conjTranspose]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : StarRing α
inst✝ : Invertible Aᴴ
⊢ Invertible (star Aᴴ)
[PROOFSTEP]
infer_instance
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
⊢ IsUnit A ↔ IsUnit (det A)
[PROOFSTEP]
simp only [← nonempty_invertible_iff_isUnit, (invertibleEquivDetInvertible A).nonempty_congr]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ IsUnit (det Aᵀ)
[PROOFSTEP]
rw [det_transpose]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ IsUnit (det A)
[PROOFSTEP]
exact h
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : ¬IsUnit (det A)
⊢ A⁻¹ = 0
[PROOFSTEP]
rw [inv_def, Ring.inverse_non_unit _ h, zero_smul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ A⁻¹ = ↑(IsUnit.unit h)⁻¹ • adjugate A
[PROOFSTEP]
rw [inv_def, ← Ring.inverse_unit h.unit, IsUnit.unit_spec]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
⊢ ⅟A = A⁻¹
[PROOFSTEP]
letI := detInvertibleOfInvertible A
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
this : Invertible (det A) := detInvertibleOfInvertible A
⊢ ⅟A = A⁻¹
[PROOFSTEP]
rw [inv_def, Ring.inverse_invertible, invOf_eq]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B : Matrix n n α
A : (Matrix n n α)ˣ
⊢ ↑A⁻¹ = (↑A)⁻¹
[PROOFSTEP]
letI := A.invertible
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B : Matrix n n α
A : (Matrix n n α)ˣ
this : Invertible ↑A := Units.invertible A
⊢ ↑A⁻¹ = (↑A)⁻¹
[PROOFSTEP]
rw [← invOf_eq_nonsing_inv, invOf_units]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
⊢ A⁻¹ = Ring.inverse A
[PROOFSTEP]
by_cases h_det : IsUnit A.det
[GOAL]
case pos
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h_det : IsUnit (det A)
⊢ A⁻¹ = Ring.inverse A
[PROOFSTEP]
cases (A.isUnit_iff_isUnit_det.mpr h_det).nonempty_invertible
[GOAL]
case pos.intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h_det : IsUnit (det A)
val✝ : Invertible A
⊢ A⁻¹ = Ring.inverse A
[PROOFSTEP]
rw [← invOf_eq_nonsing_inv, Ring.inverse_invertible]
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h_det : ¬IsUnit (det A)
⊢ A⁻¹ = Ring.inverse A
[PROOFSTEP]
have h := mt A.isUnit_iff_isUnit_det.mp h_det
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h_det : ¬IsUnit (det A)
h : ¬IsUnit A
⊢ A⁻¹ = Ring.inverse A
[PROOFSTEP]
rw [Ring.inverse_non_unit _ h, nonsing_inv_apply_not_isUnit A h_det]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
⊢ A⁻¹ᵀ = Aᵀ⁻¹
[PROOFSTEP]
rw [inv_def, inv_def, transpose_smul, det_transpose, adjugate_transpose]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : StarRing α
⊢ A⁻¹ᴴ = Aᴴ⁻¹
[PROOFSTEP]
rw [inv_def, inv_def, conjTranspose_smul, det_conjTranspose, adjugate_conjTranspose, Ring.inverse_star]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ A * A⁻¹ = 1
[PROOFSTEP]
cases (A.isUnit_iff_isUnit_det.mpr h).nonempty_invertible
[GOAL]
case intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
val✝ : Invertible A
⊢ A * A⁻¹ = 1
[PROOFSTEP]
rw [← invOf_eq_nonsing_inv, mul_invOf_self]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ A⁻¹ * A = 1
[PROOFSTEP]
cases (A.isUnit_iff_isUnit_det.mpr h).nonempty_invertible
[GOAL]
case intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
val✝ : Invertible A
⊢ A⁻¹ * A = 1
[PROOFSTEP]
rw [← invOf_eq_nonsing_inv, invOf_mul_self]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
⊢ Invertible A⁻¹
[PROOFSTEP]
rw [← invOf_eq_nonsing_inv]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
⊢ Invertible ⅟A
[PROOFSTEP]
infer_instance
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
⊢ A⁻¹⁻¹ = A
[PROOFSTEP]
simp only [← invOf_eq_nonsing_inv, invOf_invOf]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B✝ : Matrix n n α
B : Matrix m n α
h : IsUnit (det A)
⊢ B * A * A⁻¹ = B
[PROOFSTEP]
simp [Matrix.mul_assoc, mul_nonsing_inv A h]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B✝ : Matrix n n α
B : Matrix n m α
h : IsUnit (det A)
⊢ A * (A⁻¹ * B) = B
[PROOFSTEP]
simp [← Matrix.mul_assoc, mul_nonsing_inv A h]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B✝ : Matrix n n α
B : Matrix m n α
h : IsUnit (det A)
⊢ B * A⁻¹ * A = B
[PROOFSTEP]
simp [Matrix.mul_assoc, nonsing_inv_mul A h]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B✝ : Matrix n n α
B : Matrix n m α
h : IsUnit (det A)
⊢ A⁻¹ * (A * B) = B
[PROOFSTEP]
simp [← Matrix.mul_assoc, nonsing_inv_mul A h]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A✝ B✝ A B C : Matrix n n α
inst✝ : Invertible A
h : A⁻¹ * B = C
⊢ B = A * C
[PROOFSTEP]
rw [← h, mul_inv_cancel_left_of_invertible]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A✝ B✝ A B C : Matrix n n α
inst✝ : Invertible A
h : B = A * C
⊢ A⁻¹ * B = C
[PROOFSTEP]
rw [h, inv_mul_cancel_left_of_invertible]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A✝ B✝ A B C : Matrix n n α
inst✝ : Invertible A
h : B * A⁻¹ = C
⊢ B = C * A
[PROOFSTEP]
rw [← h, inv_mul_cancel_right_of_invertible]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A✝ B✝ A B C : Matrix n n α
inst✝ : Invertible A
h : B = C * A
⊢ B * A⁻¹ = C
[PROOFSTEP]
rw [h, mul_inv_cancel_right_of_invertible]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
x✝¹ x✝ : Matrix n m α
h : (fun x => A * x) x✝¹ = (fun x => A * x) x✝
⊢ x✝¹ = x✝
[PROOFSTEP]
simpa only [inv_mul_cancel_left_of_invertible] using congr_arg (A⁻¹ * ·) h
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible A
a x : Matrix m n α
hax : (fun x => x * A) a = (fun x => x * A) x
⊢ a = x
[PROOFSTEP]
simpa only [mul_inv_cancel_right_of_invertible] using congr_arg (· * A⁻¹) hax
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
⊢ A⁻¹ * A = 1 ∧ A * A⁻¹ = 1 ∨ A⁻¹ = 0
[PROOFSTEP]
by_cases h : IsUnit A.det
[GOAL]
case pos
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ A⁻¹ * A = 1 ∧ A * A⁻¹ = 1 ∨ A⁻¹ = 0
[PROOFSTEP]
exact Or.inl ⟨nonsing_inv_mul _ h, mul_nonsing_inv _ h⟩
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : ¬IsUnit (det A)
⊢ A⁻¹ * A = 1 ∧ A * A⁻¹ = 1 ∨ A⁻¹ = 0
[PROOFSTEP]
exact Or.inr (nonsing_inv_apply_not_isUnit _ h)
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ det A⁻¹ * det A = 1
[PROOFSTEP]
rw [← det_mul, A.nonsing_inv_mul h, det_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
⊢ det A⁻¹ = Ring.inverse (det A)
[PROOFSTEP]
by_cases h : IsUnit A.det
[GOAL]
case pos
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ det A⁻¹ = Ring.inverse (det A)
[PROOFSTEP]
cases h.nonempty_invertible
[GOAL]
case pos.intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
val✝ : Invertible (det A)
⊢ det A⁻¹ = Ring.inverse (det A)
[PROOFSTEP]
letI := invertibleOfDetInvertible A
[GOAL]
case pos.intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
val✝ : Invertible (det A)
this : Invertible A := invertibleOfDetInvertible A
⊢ det A⁻¹ = Ring.inverse (det A)
[PROOFSTEP]
rw [Ring.inverse_invertible, ← invOf_eq_nonsing_inv, det_invOf]
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : ¬IsUnit (det A)
⊢ det A⁻¹ = Ring.inverse (det A)
[PROOFSTEP]
cases isEmpty_or_nonempty n
[GOAL]
case neg.inl
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : ¬IsUnit (det A)
h✝ : IsEmpty n
⊢ det A⁻¹ = Ring.inverse (det A)
[PROOFSTEP]
rw [det_isEmpty, det_isEmpty, Ring.inverse_one]
[GOAL]
case neg.inr
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : ¬IsUnit (det A)
h✝ : Nonempty n
⊢ det A⁻¹ = Ring.inverse (det A)
[PROOFSTEP]
rw [Ring.inverse_non_unit _ h, nonsing_inv_apply_not_isUnit _ h, det_zero ‹_›]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ A⁻¹⁻¹ = 1 * A⁻¹⁻¹
[PROOFSTEP]
rw [Matrix.one_mul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ 1 * A⁻¹⁻¹ = A * A⁻¹ * A⁻¹⁻¹
[PROOFSTEP]
rw [A.mul_nonsing_inv h]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
h : IsUnit (det A)
⊢ A * A⁻¹ * A⁻¹⁻¹ = A
[PROOFSTEP]
rw [Matrix.mul_assoc, A⁻¹.mul_nonsing_inv (A.isUnit_nonsing_inv_det h), Matrix.mul_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
⊢ IsUnit (det A⁻¹) ↔ IsUnit (det A)
[PROOFSTEP]
rw [Matrix.det_nonsing_inv, isUnit_ring_inverse]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible (det A)
⊢ unitOfDetInvertible A = nonsingInvUnit A (_ : IsUnit (det A))
[PROOFSTEP]
ext
[GOAL]
case a.a.h
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
inst✝ : Invertible (det A)
i✝ x✝ : n
⊢ ↑(unitOfDetInvertible A) i✝ x✝ = ↑(nonsingInvUnit A (_ : IsUnit (det A))) i✝ x✝
[PROOFSTEP]
rfl
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B C : Matrix n n α
h : B * A = 1
g : C * A = 1
⊢ B = C
[PROOFSTEP]
rw [← inv_eq_left_inv h, ← inv_eq_left_inv g]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B C : Matrix n n α
h : A * B = 1
g : A * C = 1
⊢ B = C
[PROOFSTEP]
rw [← inv_eq_right_inv h, ← inv_eq_right_inv g]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B C : Matrix n n α
h : A * B = 1
g : C * A = 1
⊢ B = C
[PROOFSTEP]
rw [← inv_eq_right_inv h, ← inv_eq_left_inv g]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B C : Matrix n n α
h : A⁻¹ = B⁻¹
h' : IsUnit (det A)
⊢ A = B
[PROOFSTEP]
refine' left_inv_eq_left_inv (mul_nonsing_inv _ h') _
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B C : Matrix n n α
h : A⁻¹ = B⁻¹
h' : IsUnit (det A)
⊢ B * A⁻¹ = 1
[PROOFSTEP]
rw [h]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B C : Matrix n n α
h : A⁻¹ = B⁻¹
h' : IsUnit (det A)
⊢ B * B⁻¹ = 1
[PROOFSTEP]
refine' mul_nonsing_inv _ _
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B C : Matrix n n α
h : A⁻¹ = B⁻¹
h' : IsUnit (det A)
⊢ IsUnit (det B)
[PROOFSTEP]
rwa [← isUnit_nonsing_inv_det_iff, ← h, isUnit_nonsing_inv_det_iff]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
⊢ 0⁻¹ = 0
[PROOFSTEP]
cases' subsingleton_or_nontrivial α with ht ht
[GOAL]
case inl
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Subsingleton α
⊢ 0⁻¹ = 0
[PROOFSTEP]
simp
[GOAL]
case inr
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
⊢ 0⁻¹ = 0
[PROOFSTEP]
cases' (Fintype.card n).zero_le.eq_or_lt with hc hc
[GOAL]
case inr.inl
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
hc : 0 = Fintype.card n
⊢ 0⁻¹ = 0
[PROOFSTEP]
rw [eq_comm, Fintype.card_eq_zero_iff] at hc
[GOAL]
case inr.inl
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
hc : IsEmpty n
⊢ 0⁻¹ = 0
[PROOFSTEP]
haveI := hc
[GOAL]
case inr.inl
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
hc this : IsEmpty n
⊢ 0⁻¹ = 0
[PROOFSTEP]
ext i
[GOAL]
case inr.inl.a.h
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
hc this : IsEmpty n
i x✝ : n
⊢ 0⁻¹ i x✝ = OfNat.ofNat 0 i x✝
[PROOFSTEP]
exact (IsEmpty.false i).elim
[GOAL]
case inr.inr
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
hc : 0 < Fintype.card n
⊢ 0⁻¹ = 0
[PROOFSTEP]
have hn : Nonempty n := Fintype.card_pos_iff.mp hc
[GOAL]
case inr.inr
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
hc : 0 < Fintype.card n
hn : Nonempty n
⊢ 0⁻¹ = 0
[PROOFSTEP]
refine' nonsing_inv_apply_not_isUnit _ _
[GOAL]
case inr.inr
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
ht : Nontrivial α
hc : 0 < Fintype.card n
hn : Nonempty n
⊢ ¬IsUnit (det 0)
[PROOFSTEP]
simp [hn]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
src✝¹ : One (Matrix n n α) := one
src✝ : Inv (Matrix n n α) := inv
⊢ 1 * 1 = 1
[PROOFSTEP]
simp
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
k : α
inst✝ : Invertible k
h : IsUnit (det A)
⊢ ⅟k • A⁻¹ * k • A = 1
[PROOFSTEP]
simp [h, smul_smul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
k : αˣ
h : IsUnit (det A)
⊢ k⁻¹ • A⁻¹ * k • A = 1
[PROOFSTEP]
simp [h, smul_smul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
h : IsUnit (det A)
⊢ (adjugate A)⁻¹ = (IsUnit.unit h)⁻¹ • A
[PROOFSTEP]
refine' inv_eq_left_inv _
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
h : IsUnit (det A)
⊢ (IsUnit.unit h)⁻¹ • A * adjugate A = 1
[PROOFSTEP]
rw [smul_mul, mul_adjugate, Units.smul_def, smul_smul, h.val_inv_mul, one_smul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α✝ : Type v
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq n
inst✝³ : CommRing α✝
A B : Matrix n n α✝
α : Type u_2
inst✝² : Semiring α
v : n → α
inst✝¹ : Invertible v
inst✝ : Invertible (diagonal v)
⊢ ⅟(diagonal v) = diagonal ⅟v
[PROOFSTEP]
letI := diagonalInvertible v
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α✝ : Type v
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq n
inst✝³ : CommRing α✝
A B : Matrix n n α✝
α : Type u_2
inst✝² : Semiring α
v : n → α
inst✝¹ : Invertible v
inst✝ : Invertible (diagonal v)
this : Invertible (diagonal v) := diagonalInvertible v
⊢ ⅟(diagonal v) = diagonal ⅟v
[PROOFSTEP]
convert (rfl : ⅟(diagonal v) = _)
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
⊢ (diag ⅟(diagonal v) * v) i = OfNat.ofNat 1 i
[PROOFSTEP]
letI : Invertible (diagonal v).det := detInvertibleOfInvertible _
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ (diag ⅟(diagonal v) * v) i = OfNat.ofNat 1 i
[PROOFSTEP]
rw [invOf_eq, diag_smul, adjugate_diagonal, diag_diagonal]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ ((⅟(det (diagonal v)) • fun i => ∏ j in erase univ i, v j) * v) i = OfNat.ofNat 1 i
[PROOFSTEP]
dsimp
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ (⅟(det (diagonal v)) * ∏ j in erase univ i, v j) * v i = 1
[PROOFSTEP]
rw [mul_assoc, prod_erase_mul _ _ (Finset.mem_univ _), ← det_diagonal]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ ⅟(det (diagonal v)) * det (diagonal fun x => v x) = 1
[PROOFSTEP]
exact mul_invOf_self _
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
⊢ (v * diag ⅟(diagonal v)) i = OfNat.ofNat 1 i
[PROOFSTEP]
letI : Invertible (diagonal v).det := detInvertibleOfInvertible _
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ (v * diag ⅟(diagonal v)) i = OfNat.ofNat 1 i
[PROOFSTEP]
rw [invOf_eq, diag_smul, adjugate_diagonal, diag_diagonal]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ (v * ⅟(det (diagonal v)) • fun i => ∏ j in erase univ i, v j) i = OfNat.ofNat 1 i
[PROOFSTEP]
dsimp
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ v i * (⅟(det (diagonal v)) * ∏ j in erase univ i, v j) = 1
[PROOFSTEP]
rw [mul_left_comm, mul_prod_erase _ _ (Finset.mem_univ _), ← det_diagonal]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommRing α
A B : Matrix n n α
v : n → α
inst✝ : Invertible (diagonal v)
i : n
this : Invertible (det (diagonal v)) := detInvertibleOfInvertible (diagonal v)
⊢ ⅟(det (diagonal v)) * det (diagonal fun x => v x) = 1
[PROOFSTEP]
exact mul_invOf_self _
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
⊢ IsUnit (diagonal v) ↔ IsUnit v
[PROOFSTEP]
simp only [← nonempty_invertible_iff_isUnit, (diagonalInvertibleEquivInvertible v).nonempty_congr]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
⊢ (diagonal v)⁻¹ = diagonal (Ring.inverse v)
[PROOFSTEP]
rw [nonsing_inv_eq_ring_inverse]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
⊢ Ring.inverse (diagonal v) = diagonal (Ring.inverse v)
[PROOFSTEP]
by_cases h : IsUnit v
[GOAL]
case pos
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
h : IsUnit v
⊢ Ring.inverse (diagonal v) = diagonal (Ring.inverse v)
[PROOFSTEP]
have := isUnit_diagonal.mpr h
[GOAL]
case pos
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
h : IsUnit v
this : IsUnit (diagonal v)
⊢ Ring.inverse (diagonal v) = diagonal (Ring.inverse v)
[PROOFSTEP]
cases this.nonempty_invertible
[GOAL]
case pos.intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
h : IsUnit v
this : IsUnit (diagonal v)
val✝ : Invertible (diagonal v)
⊢ Ring.inverse (diagonal v) = diagonal (Ring.inverse v)
[PROOFSTEP]
cases h.nonempty_invertible
[GOAL]
case pos.intro.intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
h : IsUnit v
this : IsUnit (diagonal v)
val✝¹ : Invertible (diagonal v)
val✝ : Invertible v
⊢ Ring.inverse (diagonal v) = diagonal (Ring.inverse v)
[PROOFSTEP]
rw [Ring.inverse_invertible, Ring.inverse_invertible, invOf_diagonal_eq]
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
h : ¬IsUnit v
⊢ Ring.inverse (diagonal v) = diagonal (Ring.inverse v)
[PROOFSTEP]
have := isUnit_diagonal.not.mpr h
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
v : n → α
h : ¬IsUnit v
this : ¬IsUnit (diagonal v)
⊢ Ring.inverse (diagonal v) = diagonal (Ring.inverse v)
[PROOFSTEP]
rw [Ring.inverse_non_unit _ h, Pi.zero_def, diagonal_zero, Ring.inverse_non_unit _ this]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
⊢ A⁻¹⁻¹⁻¹ = A⁻¹
[PROOFSTEP]
by_cases h : IsUnit A.det
[GOAL]
case pos
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
h : IsUnit (det A)
⊢ A⁻¹⁻¹⁻¹ = A⁻¹
[PROOFSTEP]
rw [nonsing_inv_nonsing_inv _ h]
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
h : ¬IsUnit (det A)
⊢ A⁻¹⁻¹⁻¹ = A⁻¹
[PROOFSTEP]
simp [nonsing_inv_apply_not_isUnit _ h]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
⊢ (A * B)⁻¹ = B⁻¹ * A⁻¹
[PROOFSTEP]
simp only [inv_def]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B✝ A B : Matrix n n α
⊢ Ring.inverse (det (A * B)) • adjugate (A * B) = Ring.inverse (det B) • adjugate B * Ring.inverse (det A) • adjugate A
[PROOFSTEP]
rw [Matrix.smul_mul, Matrix.mul_smul, smul_smul, det_mul, adjugate_mul_distrib, Ring.mul_inverse_rev]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A B : Matrix n n α
⊢ (List.prod [])⁻¹ = List.prod (List.map Inv.inv (List.reverse []))
[PROOFSTEP]
rw [List.reverse_nil, List.map_nil, List.prod_nil, inv_one]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
Xs : List (Matrix n n α)
⊢ (List.prod (A :: Xs))⁻¹ = List.prod (List.map Inv.inv (List.reverse (A :: Xs)))
[PROOFSTEP]
rw [List.reverse_cons', List.map_concat, List.prod_concat, List.prod_cons, mul_inv_rev, list_prod_inv_reverse Xs]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
b : n → α
h : IsUnit (det A)
⊢ det A • mulVec A⁻¹ b = ↑(cramer A) b
[PROOFSTEP]
rw [cramer_eq_adjugate_mulVec, A.nonsing_inv_apply h, ← smul_mulVec_assoc, smul_smul, h.mul_val_inv, one_smul]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommRing α
A✝ B A : Matrix n n α
b : n → α
h : IsUnit (det A)
⊢ det A • vecMul b A⁻¹ = ↑(cramer Aᵀ) b
[PROOFSTEP]
rw [← A⁻¹.transpose_transpose, vecMul_transpose, transpose_nonsing_inv, ← det_transpose,
  Aᵀ.det_smul_inv_mulVec_eq_cramer _ (isUnit_det_transpose A h)]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq n
inst✝³ : CommRing α
A✝ B : Matrix n n α
inst✝² : Fintype m
inst✝¹ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
inst✝ : Invertible A
⊢ submatrix A ↑e₁ ↑e₂ * submatrix ⅟A ↑e₂ ↑e₁ = 1
[PROOFSTEP]
rw [Matrix.submatrix_mul_equiv, mul_invOf_self, submatrix_one_equiv]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq n
inst✝³ : CommRing α
A✝ B : Matrix n n α
inst✝² : Fintype m
inst✝¹ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
inst✝ : Invertible (submatrix A ↑e₁ ↑e₂)
⊢ A * submatrix ⅟(submatrix A ↑e₁ ↑e₂) ↑e₂.symm ↑e₁.symm = 1
[PROOFSTEP]
have : A = (A.submatrix e₁ e₂).submatrix e₁.symm e₂.symm := by
  simp
    -- Porting note: was
        -- conv in _ * _ =>
        --   congr
        --   rw [this]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq n
inst✝³ : CommRing α
A✝ B : Matrix n n α
inst✝² : Fintype m
inst✝¹ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
inst✝ : Invertible (submatrix A ↑e₁ ↑e₂)
⊢ A = submatrix (submatrix A ↑e₁ ↑e₂) ↑e₁.symm ↑e₂.symm
[PROOFSTEP]
simp
  -- Porting note: was
      -- conv in _ * _ =>
      --   congr
      --   rw [this]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq n
inst✝³ : CommRing α
A✝ B : Matrix n n α
inst✝² : Fintype m
inst✝¹ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
inst✝ : Invertible (submatrix A ↑e₁ ↑e₂)
this : A = submatrix (submatrix A ↑e₁ ↑e₂) ↑e₁.symm ↑e₂.symm
⊢ A * submatrix ⅟(submatrix A ↑e₁ ↑e₂) ↑e₂.symm ↑e₁.symm = 1
[PROOFSTEP]
rw [congr_arg₂ (· * ·) this rfl]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq n
inst✝³ : CommRing α
A✝ B : Matrix n n α
inst✝² : Fintype m
inst✝¹ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
inst✝ : Invertible (submatrix A ↑e₁ ↑e₂)
this : A = submatrix (submatrix A ↑e₁ ↑e₂) ↑e₁.symm ↑e₂.symm
⊢ submatrix (submatrix A ↑e₁ ↑e₂) ↑e₁.symm ↑e₂.symm * submatrix ⅟(submatrix A ↑e₁ ↑e₂) ↑e₂.symm ↑e₁.symm = 1
[PROOFSTEP]
rw [Matrix.submatrix_mul_equiv, mul_invOf_self, submatrix_one_equiv]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁶ : Fintype n
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing α
A✝ B : Matrix n n α
inst✝³ : Fintype m
inst✝² : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
inst✝¹ : Invertible A
inst✝ : Invertible (submatrix A ↑e₁ ↑e₂)
⊢ ⅟(submatrix A ↑e₁ ↑e₂) = submatrix ⅟A ↑e₂ ↑e₁
[PROOFSTEP]
letI := submatrixEquivInvertible A e₁ e₂
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁶ : Fintype n
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing α
A✝ B : Matrix n n α
inst✝³ : Fintype m
inst✝² : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
inst✝¹ : Invertible A
inst✝ : Invertible (submatrix A ↑e₁ ↑e₂)
this : Invertible (submatrix A ↑e₁ ↑e₂) := submatrixEquivInvertible A e₁ e₂
⊢ ⅟(submatrix A ↑e₁ ↑e₂) = submatrix ⅟A ↑e₂ ↑e₁
[PROOFSTEP]
convert (rfl : ⅟(A.submatrix e₁ e₂) = _)
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A✝ B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
⊢ IsUnit (submatrix A ↑e₁ ↑e₂) ↔ IsUnit A
[PROOFSTEP]
simp only [← nonempty_invertible_iff_isUnit, (submatrixEquivInvertibleEquivInvertible A _ _).nonempty_congr]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A✝ B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
⊢ (submatrix A ↑e₁ ↑e₂)⁻¹ = submatrix A⁻¹ ↑e₂ ↑e₁
[PROOFSTEP]
by_cases h : IsUnit A
[GOAL]
case pos
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A✝ B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
h : IsUnit A
⊢ (submatrix A ↑e₁ ↑e₂)⁻¹ = submatrix A⁻¹ ↑e₂ ↑e₁
[PROOFSTEP]
cases h.nonempty_invertible
[GOAL]
case pos.intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A✝ B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
h : IsUnit A
val✝ : Invertible A
⊢ (submatrix A ↑e₁ ↑e₂)⁻¹ = submatrix A⁻¹ ↑e₂ ↑e₁
[PROOFSTEP]
letI := submatrixEquivInvertible A e₁ e₂
[GOAL]
case pos.intro
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A✝ B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
h : IsUnit A
val✝ : Invertible A
this : Invertible (submatrix A ↑e₁ ↑e₂) := submatrixEquivInvertible A e₁ e₂
⊢ (submatrix A ↑e₁ ↑e₂)⁻¹ = submatrix A⁻¹ ↑e₂ ↑e₁
[PROOFSTEP]
rw [← invOf_eq_nonsing_inv, ← invOf_eq_nonsing_inv, invOf_submatrix_equiv_eq A]
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A✝ B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
h : ¬IsUnit A
⊢ (submatrix A ↑e₁ ↑e₂)⁻¹ = submatrix A⁻¹ ↑e₂ ↑e₁
[PROOFSTEP]
have := (isUnit_submatrix_equiv e₁ e₂).not.mpr h
[GOAL]
case neg
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A✝ B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
A : Matrix m m α
e₁ e₂ : n ≃ m
h : ¬IsUnit A
this : ¬IsUnit (submatrix A ↑e₁ ↑e₂)
⊢ (submatrix A ↑e₁ ↑e₂)⁻¹ = submatrix A⁻¹ ↑e₂ ↑e₁
[PROOFSTEP]
simp_rw [nonsing_inv_eq_ring_inverse, Ring.inverse_non_unit _ h, Ring.inverse_non_unit _ this, submatrix_zero,
  Pi.zero_apply]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
M : Matrix m m α
h : IsUnit M
N : Matrix m m α
⊢ det (M * N * M⁻¹) = det N
[PROOFSTEP]
rw [← h.unit_spec, ← coe_units_inv, det_units_conj]
[GOAL]
l : Type u_1
m : Type u
n : Type u'
α : Type v
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommRing α
A B : Matrix n n α
inst✝¹ : Fintype m
inst✝ : DecidableEq m
M : Matrix m m α
h : IsUnit M
N : Matrix m m α
⊢ det (M⁻¹ * N * M) = det N
[PROOFSTEP]
rw [← h.unit_spec, ← coe_units_inv, det_units_conj']


[GOAL]
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ (k : ℕ), k ≤ n → Measurable (f k)
⊢ Measurable (sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) f)
[PROOFSTEP]
simp_rw [← Nat.lt_succ_iff] at hf
[GOAL]
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ (k : ℕ), k < Nat.succ n → Measurable (f k)
⊢ Measurable (sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) f)
[PROOFSTEP]
refine' Finset.measurable_sup' _ _
[GOAL]
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ (k : ℕ), k < Nat.succ n → Measurable (f k)
⊢ ∀ (n_1 : ℕ), n_1 ∈ range (n + 1) → Measurable (f n_1)
[PROOFSTEP]
simpa [Finset.mem_range]
[GOAL]
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ (k : ℕ), k ≤ n → Measurable (f k)
⊢ Measurable fun x => sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) fun k => f k x
[PROOFSTEP]
convert Finset.measurable_range_sup' hf using 1
[GOAL]
case h.e'_5
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ (k : ℕ), k ≤ n → Measurable (f k)
⊢ (fun x => sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) fun k => f k x) =
    sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) fun k => f k
[PROOFSTEP]
ext x
[GOAL]
case h.e'_5.h
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ (k : ℕ), k ≤ n → Measurable (f k)
x : δ
⊢ (sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) fun k => f k x) =
    sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) (fun k => f k) x
[PROOFSTEP]
simp


[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
ha : a ≤ a'
hr : r ≤ 1
⊢ ↑(lineMap a b) r ≤ ↑(lineMap a' b) r
[PROOFSTEP]
simp only [lineMap_apply_module]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
ha : a ≤ a'
hr : r ≤ 1
⊢ (1 - r) • a + r • b ≤ (1 - r) • a' + r • b
[PROOFSTEP]
exact add_le_add_right (smul_le_smul_of_nonneg ha (sub_nonneg.2 hr)) _
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
ha : a < a'
hr : r < 1
⊢ ↑(lineMap a b) r < ↑(lineMap a' b) r
[PROOFSTEP]
simp only [lineMap_apply_module]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
ha : a < a'
hr : r < 1
⊢ (1 - r) • a + r • b < (1 - r) • a' + r • b
[PROOFSTEP]
exact add_lt_add_right (smul_lt_smul_of_pos ha (sub_pos.2 hr)) _
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
hb : b ≤ b'
hr : 0 ≤ r
⊢ ↑(lineMap a b) r ≤ ↑(lineMap a b') r
[PROOFSTEP]
simp only [lineMap_apply_module]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
hb : b ≤ b'
hr : 0 ≤ r
⊢ (1 - r) • a + r • b ≤ (1 - r) • a + r • b'
[PROOFSTEP]
exact add_le_add_left (smul_le_smul_of_nonneg hb hr) _
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
hb : b < b'
hr : 0 < r
⊢ ↑(lineMap a b) r < ↑(lineMap a b') r
[PROOFSTEP]
simp only [lineMap_apply_module]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
hb : b < b'
hr : 0 < r
⊢ (1 - r) • a + r • b < (1 - r) • a + r • b'
[PROOFSTEP]
exact add_lt_add_left (smul_lt_smul_of_pos hb hr) _
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
ha : a < a'
hb : b < b'
h₀ : 0 ≤ r
h₁ : r ≤ 1
⊢ ↑(lineMap a b) r < ↑(lineMap a' b') r
[PROOFSTEP]
rcases h₀.eq_or_lt with (rfl | h₀)
[GOAL]
case inl
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r' : k
ha : a < a'
hb : b < b'
h₀ : 0 ≤ 0
h₁ : 0 ≤ 1
⊢ ↑(lineMap a b) 0 < ↑(lineMap a' b') 0
[PROOFSTEP]
simpa
[GOAL]
case inr
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
ha : a < a'
hb : b < b'
h₀✝ : 0 ≤ r
h₁ : r ≤ 1
h₀ : 0 < r
⊢ ↑(lineMap a b) r < ↑(lineMap a' b') r
[PROOFSTEP]
exact (lineMap_mono_left ha.le h₁).trans_lt (lineMap_strict_mono_right hb h₀)
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
h : r < r'
⊢ ↑(lineMap a b) r < ↑(lineMap a b) r' ↔ a < b
[PROOFSTEP]
simp only [lineMap_apply_module]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
h : r < r'
⊢ (1 - r) • a + r • b < (1 - r') • a + r' • b ↔ a < b
[PROOFSTEP]
rw [← lt_sub_iff_add_lt, add_sub_assoc, ← sub_lt_iff_lt_add', ← sub_smul, ← sub_smul, sub_sub_sub_cancel_left,
  smul_lt_smul_iff_of_pos (sub_pos.2 h)]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
h : 0 < r
⊢ a < ↑(lineMap a b) r ↔ ↑(lineMap a b) 0 < ↑(lineMap a b) r
[PROOFSTEP]
rw [lineMap_apply_zero]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : OrderedRing k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a a' b b' : E
r r' : k
h : r < 1
⊢ ↑(lineMap a b) r < b ↔ ↑(lineMap a b) r < ↑(lineMap a b) 1
[PROOFSTEP]
rw [lineMap_apply_one]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a b : E
r r' : k
h : r < r'
⊢ ↑(lineMap a b) r ≤ ↑(lineMap a b) r' ↔ a ≤ b
[PROOFSTEP]
simp only [lineMap_apply_module]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a b : E
r r' : k
h : r < r'
⊢ (1 - r) • a + r • b ≤ (1 - r') • a + r' • b ↔ a ≤ b
[PROOFSTEP]
rw [← le_sub_iff_add_le, add_sub_assoc, ← sub_le_iff_le_add', ← sub_smul, ← sub_smul, sub_sub_sub_cancel_left,
  smul_le_smul_iff_of_pos (sub_pos.2 h)]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a b : E
r r' : k
h : 0 < r
⊢ a ≤ ↑(lineMap a b) r ↔ ↑(lineMap a b) 0 ≤ ↑(lineMap a b) r
[PROOFSTEP]
rw [lineMap_apply_zero]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
a b : E
r r' : k
h : r < 1
⊢ ↑(lineMap a b) r ≤ b ↔ ↑(lineMap a b) r ≤ ↑(lineMap a b) 1
[PROOFSTEP]
rw [lineMap_apply_one]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r : k
h : 0 < r * (b - a)
⊢ f (↑(lineMap a b) r) ≤ ↑(lineMap (f a) (f b)) r ↔ slope f a (↑(lineMap a b) r) ≤ slope f a b
[PROOFSTEP]
rw [lineMap_apply, lineMap_apply, slope, slope, vsub_eq_sub, vsub_eq_sub, vsub_eq_sub, vadd_eq_add, vadd_eq_add,
  smul_eq_mul, add_sub_cancel, smul_sub, smul_sub, smul_sub, sub_le_iff_le_add, mul_inv_rev, mul_smul, mul_smul, ←
  smul_sub, ← smul_sub, ← smul_add, smul_smul, ← mul_inv_rev, inv_smul_le_iff h, smul_smul,
  mul_inv_cancel_right₀ (right_ne_zero_of_mul h.ne'), smul_add, smul_inv_smul₀ (left_ne_zero_of_mul h.ne')]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r : k
h : 0 < (1 - r) * (b - a)
⊢ f (↑(lineMap a b) r) ≤ ↑(lineMap (f a) (f b)) r ↔ slope f a b ≤ slope f (↑(lineMap a b) r) b
[PROOFSTEP]
rw [← lineMap_apply_one_sub, ← lineMap_apply_one_sub _ _ r]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r : k
h : 0 < (1 - r) * (b - a)
⊢ f (↑(lineMap b a) (1 - r)) ≤ ↑(lineMap (f b) (f a)) (1 - r) ↔ slope f a b ≤ slope f (↑(lineMap b a) (1 - r)) b
[PROOFSTEP]
revert h
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r : k
⊢ 0 < (1 - r) * (b - a) →
    (f (↑(lineMap b a) (1 - r)) ≤ ↑(lineMap (f b) (f a)) (1 - r) ↔ slope f a b ≤ slope f (↑(lineMap b a) (1 - r)) b)
[PROOFSTEP]
generalize 1 - r = r'
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r r' : k
⊢ 0 < r' * (b - a) → (f (↑(lineMap b a) r') ≤ ↑(lineMap (f b) (f a)) r' ↔ slope f a b ≤ slope f (↑(lineMap b a) r') b)
[PROOFSTEP]
clear! r
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r' : k
⊢ 0 < r' * (b - a) → (f (↑(lineMap b a) r') ≤ ↑(lineMap (f b) (f a)) r' ↔ slope f a b ≤ slope f (↑(lineMap b a) r') b)
[PROOFSTEP]
intro h
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r' : k
h : 0 < r' * (b - a)
⊢ f (↑(lineMap b a) r') ≤ ↑(lineMap (f b) (f a)) r' ↔ slope f a b ≤ slope f (↑(lineMap b a) r') b
[PROOFSTEP]
simp_rw [lineMap_apply, slope, vsub_eq_sub, vadd_eq_add, smul_eq_mul]
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r' : k
h : 0 < r' * (b - a)
⊢ f (r' * (a - b) + b) ≤ r' • (f a - f b) + f b ↔
    (b - a)⁻¹ • (f b - f a) ≤ (b - (r' * (a - b) + b))⁻¹ • (f b - f (r' * (a - b) + b))
[PROOFSTEP]
rw [sub_add_eq_sub_sub_swap, sub_self, zero_sub, neg_mul_eq_mul_neg, neg_sub, le_inv_smul_iff h, smul_smul,
  mul_inv_cancel_right₀, le_sub_comm, ← neg_sub (f b), smul_neg, neg_add_eq_sub]
[GOAL]
case h
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r' : k
h : 0 < r' * (b - a)
⊢ b - a ≠ 0
[PROOFSTEP]
exact right_ne_zero_of_mul h.ne'
[GOAL]
k : Type u_1
E : Type u_2
PE : Type u_3
inst✝³ : LinearOrderedField k
inst✝² : OrderedAddCommGroup E
inst✝¹ : Module k E
inst✝ : OrderedSMul k E
f : k → E
a b r : k
hab : a < b
h₀ : 0 < r
h₁ : r < 1
⊢ f (↑(lineMap a b) r) ≤ ↑(lineMap (f a) (f b)) r ↔ slope f a (↑(lineMap a b) r) ≤ slope f (↑(lineMap a b) r) b
[PROOFSTEP]
rw [map_le_lineMap_iff_slope_le_slope_left (mul_pos h₀ (sub_pos.2 hab)), ← lineMap_slope_lineMap_slope_lineMap f a b r,
  right_le_lineMap_iff_le h₁]


[GOAL]
R : Type u_1
S✝ : Type u_2
M✝ : Type u_3
A : Type u_4
inst✝⁴ : Semiring S✝
inst✝³ : AddCommMonoid M✝
inst✝² : CommSemiring R
inst✝¹ : Algebra R S✝
inst✝ : Module S✝ M✝
r : R
S : S✝
M : RestrictScalars R S✝ M✝
⊢ (r • S) • M = r • S • M
[PROOFSTEP]
rw [Algebra.smul_def, mul_smul]
[GOAL]
R : Type u_1
S✝ : Type u_2
M✝ : Type u_3
A : Type u_4
inst✝⁴ : Semiring S✝
inst✝³ : AddCommMonoid M✝
inst✝² : CommSemiring R
inst✝¹ : Algebra R S✝
inst✝ : Module S✝ M✝
r : R
S : S✝
M : RestrictScalars R S✝ M✝
⊢ ↑(algebraMap R S✝) r • S • M = r • S • M
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
M : Type u_3
A : Type u_4
inst✝⁴ : AddCommMonoid M
inst✝³ : CommSemiring R
inst✝² : Semiring S
inst✝¹ : Algebra R S
inst✝ : Module S M
r : R
s : S
x : M
⊢ ↑(AddEquiv.symm (addEquiv R S M)) ((r • s) • x) = r • ↑(AddEquiv.symm (addEquiv R S M)) (s • x)
[PROOFSTEP]
rw [Algebra.smul_def, mul_smul]
[GOAL]
R : Type u_1
S : Type u_2
M : Type u_3
A : Type u_4
inst✝⁴ : AddCommMonoid M
inst✝³ : CommSemiring R
inst✝² : Semiring S
inst✝¹ : Algebra R S
inst✝ : Module S M
r : R
s : S
x : M
⊢ ↑(AddEquiv.symm (addEquiv R S M)) (↑(algebraMap R S) r • s • x) = r • ↑(AddEquiv.symm (addEquiv R S M)) (s • x)
[PROOFSTEP]
rfl


[GOAL]
X✝ Y✝ : CompHaus
a₁✝ a₂✝ : X✝ ⟶ Y✝
h : (compHausToTop ⋙ topToLocale).map a₁✝ = (compHausToTop ⋙ topToLocale).map a₂✝
⊢ a₁✝ = a₂✝
[PROOFSTEP]
dsimp at h
[GOAL]
X✝ Y✝ : CompHaus
a₁✝ a₂✝ : X✝ ⟶ Y✝
h : (Opens.comap a₁✝).op = (Opens.comap a₂✝).op
⊢ a₁✝ = a₂✝
[PROOFSTEP]
exact Opens.comap_injective (Quiver.Hom.op_inj h)


[GOAL]
α : Type u_1
inst✝ : Monoid α
a b : α
h : a = b
⊢ a ∣ b
[PROOFSTEP]
rw [h]
[GOAL]
α : Type u_1
inst✝ : CommSemigroup α
a b c✝ c : α
h : c * a = b
⊢ a * ?m.8269 c h = b
[PROOFSTEP]
rw [mul_comm] at h
[GOAL]
α : Type u_1
inst✝ : CommSemigroup α
a b c✝ c : α
h✝ : c * a = b
h : a * c = b
⊢ a * ?m.8269 c h✝ = b
[PROOFSTEP]
apply h
[GOAL]
α : Type u_1
inst✝ : CommSemigroup α
a b c : α
⊢ (∃ c, b = c * a) → a ∣ b
[PROOFSTEP]
rintro ⟨c, rfl⟩
[GOAL]
case intro
α : Type u_1
inst✝ : CommSemigroup α
a c✝ c : α
⊢ a ∣ c * a
[PROOFSTEP]
exact ⟨c, mul_comm _ _⟩
[GOAL]
α : Type u_1
inst✝ : CommSemigroup α
a b c✝ : α
h : a ∣ b
c : α
⊢ a ∣ c * b
[PROOFSTEP]
rw [mul_comm]
[GOAL]
α : Type u_1
inst✝ : CommSemigroup α
a b c✝ : α
h : a ∣ b
c : α
⊢ a ∣ b * c
[PROOFSTEP]
exact h.mul_right _
[GOAL]
α : Type u_1
inst✝ : CommSemigroup α
a✝ b c✝ a c e f : α
⊢ a * e * (c * f) = a * c * (e * f)
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
inst✝ : CommSemigroup α
a b c : α
h : a * b ∣ c
d : α
ceq : c = a * b * d
⊢ b * (a * d) = c
[PROOFSTEP]
simp [ceq]
[GOAL]
α : Type u_1
inst✝ : CommMonoid α
a✝ b✝ a b : α
h : a ∣ b
⊢ a ^ 0 ∣ b ^ 0
[PROOFSTEP]
rw [pow_zero, pow_zero]
[GOAL]
α : Type u_1
inst✝ : CommMonoid α
a✝ b✝ a b : α
h : a ∣ b
n : ℕ
⊢ a ^ (n + 1) ∣ b ^ (n + 1)
[PROOFSTEP]
rw [pow_succ, pow_succ]
[GOAL]
α : Type u_1
inst✝ : CommMonoid α
a✝ b✝ a b : α
h : a ∣ b
n : ℕ
⊢ a * a ^ n ∣ b * b ^ n
[PROOFSTEP]
exact mul_dvd_mul h (pow_dvd_pow_of_dvd h n)


[GOAL]
a b : ℤ
⊢ natAbs a = natAbs b ↔ Associated a b
[PROOFSTEP]
refine' Int.natAbs_eq_natAbs_iff.trans _
[GOAL]
a b : ℤ
⊢ a = b ∨ a = -b ↔ Associated a b
[PROOFSTEP]
constructor
[GOAL]
case mp
a b : ℤ
⊢ a = b ∨ a = -b → Associated a b
[PROOFSTEP]
rintro (rfl | rfl)
[GOAL]
case mp.inl
a : ℤ
⊢ Associated a a
[PROOFSTEP]
rfl
[GOAL]
case mp.inr
b : ℤ
⊢ Associated (-b) b
[PROOFSTEP]
exact ⟨-1, by simp⟩
[GOAL]
b : ℤ
⊢ -b * ↑(-1) = b
[PROOFSTEP]
simp
[GOAL]
case mpr
a b : ℤ
⊢ Associated a b → a = b ∨ a = -b
[PROOFSTEP]
rintro ⟨u, rfl⟩
[GOAL]
case mpr.intro
a : ℤ
u : ℤˣ
⊢ a = a * ↑u ∨ a = -(a * ↑u)
[PROOFSTEP]
obtain rfl | rfl := Int.units_eq_one_or u
[GOAL]
case mpr.intro.inl
a : ℤ
⊢ a = a * ↑1 ∨ a = -(a * ↑1)
[PROOFSTEP]
exact Or.inl (by simp)
[GOAL]
a : ℤ
⊢ a = a * ↑1
[PROOFSTEP]
simp
[GOAL]
case mpr.intro.inr
a : ℤ
⊢ a = a * ↑(-1) ∨ a = -(a * ↑(-1))
[PROOFSTEP]
exact Or.inr (by simp)
[GOAL]
a : ℤ
⊢ a = -(a * ↑(-1))
[PROOFSTEP]
simp


[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f fab : α → β
fbc : β → γ
ga ga' : α → α
gb gb' : β → β
gc gc' : γ → γ
h : Semiconj f ga gb
h' : Semiconj f ga' gb'
x : α
⊢ f ((ga ∘ ga') x) = (gb ∘ gb') (f x)
[PROOFSTEP]
simp only [comp_apply, h.eq, h'.eq]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f fab : α → β
fbc : β → γ
ga ga' : α → α
gb gb' : β → β
gc gc' : γ → γ
hab : Semiconj fab ga gb
hbc : Semiconj fbc gb gc
x : α
⊢ (fbc ∘ fab) (ga x) = gc ((fbc ∘ fab) x)
[PROOFSTEP]
simp only [comp_apply, hab.eq, hbc.eq]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f fab : α → β
fbc : β → γ
ga ga' : α → α
gb gb' : β → β
gc gc' : γ → γ
h : Semiconj f ga gb
ha : RightInverse ga' ga
hb : LeftInverse gb' gb
x : α
⊢ f (ga' x) = gb' (f x)
[PROOFSTEP]
rw [← hb (f (ga' x)), ← h.eq, ha x]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
f' : β → γ
gc : γ → γ → γ
hf' : Semiconj₂ f' gb gc
hf : Semiconj₂ f ga gb
x y : α
⊢ (f' ∘ f) (ga x y) = gc ((f' ∘ f) x) ((f' ∘ f) y)
[PROOFSTEP]
simp only [hf'.eq, hf.eq, comp_apply]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsAssociative α ga
h : Semiconj₂ f ga gb
h_surj : Surjective f
x₁ x₂ x₃ : α
⊢ gb (gb (f x₁) (f x₂)) (f x₃) = gb (f x₁) (gb (f x₂) (f x₃))
[PROOFSTEP]
simp only [← h.eq, @IsAssociative.assoc _ ga]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsAssociative β gb
h : Semiconj₂ f ga gb
h_inj : Injective f
x₁ x₂ x₃ : α
⊢ f (ga (ga x₁ x₂) x₃) = f (ga x₁ (ga x₂ x₃))
[PROOFSTEP]
simp only [h.eq, @IsAssociative.assoc _ gb]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsIdempotent α ga
h : Semiconj₂ f ga gb
h_surj : Surjective f
x : α
⊢ gb (f x) (f x) = f x
[PROOFSTEP]
simp only [← h.eq, @IsIdempotent.idempotent _ ga]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsIdempotent β gb
h : Semiconj₂ f ga gb
h_inj : Injective f
x : α
⊢ f (ga x x) = f x
[PROOFSTEP]
rw [h.eq, @IsIdempotent.idempotent _ gb]


[GOAL]
σ : Type u
R : Type v
inst✝² : CommSemiring R
inst✝¹ : Nonempty σ
inst✝ : Nontrivial R
⊢ max (lift #(σ →₀ ℕ)) (lift #R) = max (max (lift #R) (lift #σ)) ℵ₀
[PROOFSTEP]
rw [mk_finsupp_nat, max_assoc, lift_max, lift_aleph0, max_comm]
[GOAL]
σ✝ : Type u
R✝ : Type v
inst✝¹ : CommSemiring R✝
σ : Type u
R : Type v
inst✝ : CommSemiring R
⊢ #(MvPolynomial σ R) ≤ max (max (lift #R) (lift #σ)) ℵ₀
[PROOFSTEP]
cases subsingleton_or_nontrivial R
[GOAL]
case inl
σ✝ : Type u
R✝ : Type v
inst✝¹ : CommSemiring R✝
σ : Type u
R : Type v
inst✝ : CommSemiring R
h✝ : Subsingleton R
⊢ #(MvPolynomial σ R) ≤ max (max (lift #R) (lift #σ)) ℵ₀
[PROOFSTEP]
exact (mk_eq_one _).trans_le (le_max_of_le_right one_le_aleph0)
[GOAL]
case inr
σ✝ : Type u
R✝ : Type v
inst✝¹ : CommSemiring R✝
σ : Type u
R : Type v
inst✝ : CommSemiring R
h✝ : Nontrivial R
⊢ #(MvPolynomial σ R) ≤ max (max (lift #R) (lift #σ)) ℵ₀
[PROOFSTEP]
cases isEmpty_or_nonempty σ
[GOAL]
case inr.inl
σ✝ : Type u
R✝ : Type v
inst✝¹ : CommSemiring R✝
σ : Type u
R : Type v
inst✝ : CommSemiring R
h✝¹ : Nontrivial R
h✝ : IsEmpty σ
⊢ #(MvPolynomial σ R) ≤ max (max (lift #R) (lift #σ)) ℵ₀
[PROOFSTEP]
exact cardinal_mk_eq_lift.trans_le (le_max_of_le_left <| le_max_left _ _)
[GOAL]
case inr.inr
σ✝ : Type u
R✝ : Type v
inst✝¹ : CommSemiring R✝
σ : Type u
R : Type v
inst✝ : CommSemiring R
h✝¹ : Nontrivial R
h✝ : Nonempty σ
⊢ #(MvPolynomial σ R) ≤ max (max (lift #R) (lift #σ)) ℵ₀
[PROOFSTEP]
exact cardinal_mk_eq_max_lift.le
[GOAL]
σ R : Type u
inst✝² : CommSemiring R
inst✝¹ : Nonempty σ
inst✝ : Nontrivial R
⊢ #(MvPolynomial σ R) = max (max #R #σ) ℵ₀
[PROOFSTEP]
simp
[GOAL]
σ R : Type u
inst✝ : CommSemiring R
⊢ max (max (lift #R) (lift #σ)) ℵ₀ ≤ max (max #R #σ) ℵ₀
[PROOFSTEP]
rw [lift_id, lift_id]


[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : (⨂[R]^i) M
b : (⨂[R]^j) M
⊢ ↑toTensorAlgebra (GradedMonoid.GMul.mul a b) = ↑toTensorAlgebra a * ↑toTensorAlgebra b
[PROOFSTEP]
rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ← LinearMap.compl₂_apply, ←
  LinearMap.comp_apply]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : (⨂[R]^i) M
b : (⨂[R]^j) M
⊢ ↑(↑(LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra) a)
      b =
    ↑(↑(LinearMap.comp (LinearMap.compl₂ (LinearMap.mul R ((fun x => TensorAlgebra R M) a)) toTensorAlgebra)
              toTensorAlgebra)
          a)
      b
[PROOFSTEP]
refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : (⨂[R]^i) M
b : (⨂[R]^j) M
⊢ LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra =
    LinearMap.comp (LinearMap.compl₂ (LinearMap.mul R ((fun x => TensorAlgebra R M) a)) toTensorAlgebra) toTensorAlgebra
[PROOFSTEP]
clear! a b
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : (⨂[R]^i) M
⊢ LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra =
    LinearMap.comp (LinearMap.compl₂ (LinearMap.mul R ((fun x => TensorAlgebra R M) a)) toTensorAlgebra) toTensorAlgebra
[PROOFSTEP]
ext
  (a b)
    -- Porting note: pulled the next two lines out of the long `simp only` below.
[GOAL]
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a✝ : (⨂[R]^i) M
a : Fin i → M
b : Fin j → M
⊢ ↑(LinearMap.compMultilinearMap
          (↑(LinearMap.compMultilinearMap
                (LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv)
                  toTensorAlgebra)
                (PiTensorProduct.tprod R))
            a)
          (PiTensorProduct.tprod R))
      b =
    ↑(LinearMap.compMultilinearMap
          (↑(LinearMap.compMultilinearMap
                (LinearMap.comp (LinearMap.compl₂ (LinearMap.mul R ((fun x => TensorAlgebra R M) a✝)) toTensorAlgebra)
                  toTensorAlgebra)
                (PiTensorProduct.tprod R))
            a)
          (PiTensorProduct.tprod R))
      b
[PROOFSTEP]
simp only [LinearMap.compMultilinearMap_apply]
[GOAL]
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a✝ : (⨂[R]^i) M
a : Fin i → M
b : Fin j → M
⊢ ↑(↑(LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra)
          (↑(PiTensorProduct.tprod R) a))
      (↑(PiTensorProduct.tprod R) b) =
    ↑(↑(LinearMap.comp (LinearMap.compl₂ (LinearMap.mul R ((fun x => TensorAlgebra R M) a✝)) toTensorAlgebra)
              toTensorAlgebra)
          (↑(PiTensorProduct.tprod R) a))
      (↑(PiTensorProduct.tprod R) b)
[PROOFSTEP]
rw [LinearMap.compr₂_apply, ← gMul_eq_coe_linearMap]
[GOAL]
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a✝ : (⨂[R]^i) M
a : Fin i → M
b : Fin j → M
⊢ ↑toTensorAlgebra (GradedMonoid.GMul.mul (↑(PiTensorProduct.tprod R) a) (↑(PiTensorProduct.tprod R) b)) =
    ↑(↑(LinearMap.comp (LinearMap.compl₂ (LinearMap.mul R ((fun x => TensorAlgebra R M) a✝)) toTensorAlgebra)
              toTensorAlgebra)
          (↑(PiTensorProduct.tprod R) a))
      (↑(PiTensorProduct.tprod R) b)
[PROOFSTEP]
simp only [LinearMap.compr₂_apply, LinearMap.mul_apply', LinearMap.compl₂_apply, LinearMap.comp_apply,
  LinearMap.compMultilinearMap_apply, PiTensorProduct.lift.tprod, TensorPower.tprod_mul_tprod,
  TensorPower.toTensorAlgebra_tprod, TensorAlgebra.tprod_apply, ← gMul_eq_coe_linearMap]
[GOAL]
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a✝ : (⨂[R]^i) M
a : Fin i → M
b : Fin j → M
⊢ List.prod (List.ofFn fun i_1 => ↑(TensorAlgebra.ι R) (Fin.append a b i_1)) =
    List.prod (List.ofFn fun i => ↑(TensorAlgebra.ι R) (a i)) *
      List.prod (List.ofFn fun i => ↑(TensorAlgebra.ι R) (b i))
[PROOFSTEP]
refine' Eq.trans _ List.prod_append
[GOAL]
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a✝ : (⨂[R]^i) M
a : Fin i → M
b : Fin j → M
⊢ List.prod (List.ofFn fun i_1 => ↑(TensorAlgebra.ι R) (Fin.append a b i_1)) =
    List.prod ((List.ofFn fun i => ↑(TensorAlgebra.ι R) (a i)) ++ List.ofFn fun i => ↑(TensorAlgebra.ι R) (b i))
[PROOFSTEP]
apply congr_arg
[GOAL]
case H.H.H.H.h
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a✝ : (⨂[R]^i) M
a : Fin i → M
b : Fin j → M
⊢ (List.ofFn fun i_1 => ↑(TensorAlgebra.ι R) (Fin.append a b i_1)) =
    (List.ofFn fun i => ↑(TensorAlgebra.ι R) (a i)) ++ List.ofFn fun i => ↑(TensorAlgebra.ι R) (b i)
[PROOFSTEP]
erw [← List.map_ofFn _ (TensorAlgebra.ι R), ← List.map_ofFn _ (TensorAlgebra.ι R), ←
  List.map_ofFn _ (TensorAlgebra.ι R), ← List.map_append, List.ofFn_fin_append]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r : R
⊢ ↑toTensorAlgebra (↑DirectSum.GAlgebra.toFun r) = ↑(algebraMap R (TensorAlgebra R M)) r
[PROOFSTEP]
rw [TensorPower.galgebra_toFun_def, TensorPower.algebraMap₀_eq_smul_one, LinearMap.map_smul,
  TensorPower.toTensorAlgebra_gOne, Algebra.algebraMap_eq_smul_one]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
⊢ AlgHom.comp ofDirectSum toDirectSum = AlgHom.id R (TensorAlgebra R M)
[PROOFSTEP]
ext
[GOAL]
case w.h
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x✝ : M
⊢ ↑(LinearMap.comp (AlgHom.toLinearMap (AlgHom.comp ofDirectSum toDirectSum)) (ι R)) x✝ =
    ↑(LinearMap.comp (AlgHom.toLinearMap (AlgHom.id R (TensorAlgebra R M))) (ι R)) x✝
[PROOFSTEP]
simp [DirectSum.lof_eq_of, tprod_apply]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n m : ℕ
h : n = m
x : (⨂[R]^n) M
⊢ GradedMonoid.mk m (↑(PiTensorProduct.reindex R M (Fin.castIso h).toEquiv) x) = GradedMonoid.mk n x
[PROOFSTEP]
rw [Fin.castIso_to_equiv, mk_reindex_cast h]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
[PROOFSTEP]
refine' Fin.consInduction _ _ x
[GOAL]
case refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x : Fin 1), Fin.elim0 a)) (List.finRange 0)) =
    GradedMonoid.mk 0 (↑(PiTensorProduct.tprod R) Fin.elim0)
[PROOFSTEP]
clear x
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ ∀ {n : ℕ} (x₀ : M) (x : Fin n → M),
    List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
        GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x) →
      List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), Fin.cons x₀ x a)) (List.finRange (n + 1))) =
        GradedMonoid.mk (n + 1) (↑(PiTensorProduct.tprod R) (Fin.cons x₀ x))
[PROOFSTEP]
clear x
[GOAL]
case refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
⊢ List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x : Fin 1), Fin.elim0 a)) (List.finRange 0)) =
    GradedMonoid.mk 0 (↑(PiTensorProduct.tprod R) Fin.elim0)
[PROOFSTEP]
rw [List.finRange_zero, List.map_nil, List.prod_nil]
[GOAL]
case refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
⊢ 1 = GradedMonoid.mk 0 (↑(PiTensorProduct.tprod R) Fin.elim0)
[PROOFSTEP]
rfl
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
⊢ ∀ {n : ℕ} (x₀ : M) (x : Fin n → M),
    List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
        GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x) →
      List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), Fin.cons x₀ x a)) (List.finRange (n + 1))) =
        GradedMonoid.mk (n + 1) (↑(PiTensorProduct.tprod R) (Fin.cons x₀ x))
[PROOFSTEP]
intro n x₀ x ih
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), Fin.cons x₀ x a)) (List.finRange (n + 1))) =
    GradedMonoid.mk (n + 1) (↑(PiTensorProduct.tprod R) (Fin.cons x₀ x))
[PROOFSTEP]
rw [List.finRange_succ_eq_map, List.map_cons, List.prod_cons, List.map_map]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), Fin.cons x₀ x 0) *
      List.prod
        (List.map ((fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), Fin.cons x₀ x a)) ∘ Fin.succ) (List.finRange n)) =
    GradedMonoid.mk (n + 1) (↑(PiTensorProduct.tprod R) (Fin.cons x₀ x))
[PROOFSTEP]
simp_rw [Function.comp, Fin.cons_zero, Fin.cons_succ]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ GradedMonoid.mk 1 (⨂ₜ[R] (x : Fin 1), x₀) *
      List.prod (List.map (fun x_1 => GradedMonoid.mk 1 (⨂ₜ[R] (x_2 : Fin 1), x x_1)) (List.finRange n)) =
    GradedMonoid.mk (n + 1) (↑(PiTensorProduct.tprod R) (Fin.cons x₀ x))
[PROOFSTEP]
rw [ih, GradedMonoid.mk_mul_mk, TensorPower.tprod_mul_tprod]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ GradedMonoid.mk (1 + n) (↑(PiTensorProduct.tprod R) (Fin.append (fun x => x₀) x)) =
    GradedMonoid.mk (n + 1) (↑(PiTensorProduct.tprod R) (Fin.cons x₀ x))
[PROOFSTEP]
refine' TensorPower.gradedMonoid_eq_of_cast (add_comm _ _) _
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ ↑(TensorPower.cast R M (_ : 1 + n = n + 1))
      (GradedMonoid.mk (1 + n) (↑(PiTensorProduct.tprod R) (Fin.append (fun x => x₀) x))).snd =
    (GradedMonoid.mk (n + 1) (↑(PiTensorProduct.tprod R) (Fin.cons x₀ x))).snd
[PROOFSTEP]
dsimp only [GradedMonoid.mk]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ ↑(TensorPower.cast R M (_ : 1 + n = n + 1)) (↑(PiTensorProduct.tprod R) (Fin.append (fun x => x₀) x)) =
    ↑(PiTensorProduct.tprod R) (Fin.cons x₀ x)
[PROOFSTEP]
rw [TensorPower.cast_tprod]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ ↑(PiTensorProduct.tprod R) (Fin.append (fun x => x₀) x ∘ ↑(Fin.castIso (_ : n + 1 = 1 + n))) =
    ↑(PiTensorProduct.tprod R) (Fin.cons x₀ x)
[PROOFSTEP]
simp_rw [Fin.append_left_eq_cons, Function.comp]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ n : ℕ
x₀ : M
x : Fin n → M
ih :
  List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
⊢ (⨂ₜ[R] (x_1 : Fin (n + 1)),
      Fin.cons x₀ x (↑(Fin.castIso (_ : 1 + n = n + 1)) (↑(Fin.castIso (_ : n + 1 = 1 + n)) x_1))) =
    ↑(PiTensorProduct.tprod R) (Fin.cons x₀ x)
[PROOFSTEP]
congr 1 with i
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ ↑toDirectSum (↑(tprod R M n) x) = ↑(DirectSum.of (fun i => (⨂[R]^i) M) n) (↑(PiTensorProduct.tprod R) x)
[PROOFSTEP]
rw [tprod_apply, AlgHom.map_list_prod, List.map_ofFn]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ List.prod (List.ofFn (↑toDirectSum ∘ fun i => ↑(ι R) (x i))) =
    ↑(DirectSum.of (fun i => (⨂[R]^i) M) n) (↑(PiTensorProduct.tprod R) x)
[PROOFSTEP]
simp_rw [Function.comp, toDirectSum_ι]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ List.prod (List.ofFn fun x_1 => ↑(DirectSum.of (fun n => (⨂[R]^n) M) 1) (⨂ₜ[R] (x_2 : Fin 1), x x_1)) =
    ↑(DirectSum.of (fun i => (⨂[R]^i) M) n) (↑(PiTensorProduct.tprod R) x)
[PROOFSTEP]
rw [DirectSum.list_prod_ofFn_of_eq_dProd]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ ↑(DirectSum.of (fun n => (⨂[R]^n) M) (List.dProdIndex (List.finRange n) fun x => 1))
      (List.dProd (List.finRange n) (fun x => 1) fun x_1 => ⨂ₜ[R] (x_2 : Fin 1), x x_1) =
    ↑(DirectSum.of (fun i => (⨂[R]^i) M) n) (↑(PiTensorProduct.tprod R) x)
[PROOFSTEP]
apply DirectSum.of_eq_of_gradedMonoid_eq
[GOAL]
case h
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ GradedMonoid.mk (List.dProdIndex (List.finRange n) fun x => 1)
      (List.dProd (List.finRange n) (fun x => 1) fun x_1 => ⨂ₜ[R] (x_2 : Fin 1), x x_1) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
[PROOFSTEP]
rw [GradedMonoid.mk_list_dProd]
[GOAL]
case h
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : Fin n → M
⊢ List.prod (List.map (fun a => GradedMonoid.mk 1 (⨂ₜ[R] (x_1 : Fin 1), x a)) (List.finRange n)) =
    GradedMonoid.mk n (↑(PiTensorProduct.tprod R) x)
[PROOFSTEP]
rw [TensorPower.list_prod_gradedMonoid_mk_single]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
⊢ AlgHom.comp toDirectSum ofDirectSum = AlgHom.id R (⨁ (n : ℕ), (⨂[R]^n) M)
[PROOFSTEP]
ext
[GOAL]
case h.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i✝ : ℕ
x✝ : Fin i✝ → M
⊢ ↑(LinearMap.compMultilinearMap
          (LinearMap.comp (AlgHom.toLinearMap (AlgHom.comp toDirectSum ofDirectSum))
            (DirectSum.lof R ℕ (fun i => (⨂[R]^i) M) i✝))
          (PiTensorProduct.tprod R))
      x✝ =
    ↑(LinearMap.compMultilinearMap
          (LinearMap.comp (AlgHom.toLinearMap (AlgHom.id R (⨁ (n : ℕ), (⨂[R]^n) M)))
            (DirectSum.lof R ℕ (fun i => (⨂[R]^i) M) i✝))
          (PiTensorProduct.tprod R))
      x✝
[PROOFSTEP]
simp [DirectSum.lof_eq_of, -tprod_apply, toDirectSum_tensorPower_tprod]


[GOAL]
x y : ℕ
⊢ gcd x y = if x = 0 then y else gcd (y % x) x
[PROOFSTEP]
cases x
[GOAL]
case zero
y : ℕ
⊢ gcd zero y = if zero = 0 then y else gcd (y % zero) zero
[PROOFSTEP]
simp [Nat.gcd_succ]
[GOAL]
case succ
y n✝ : ℕ
⊢ gcd (succ n✝) y = if succ n✝ = 0 then y else gcd (y % succ n✝) (succ n✝)
[PROOFSTEP]
simp [Nat.gcd_succ]


[GOAL]
α : Type u
b : Bool
a : α
⊢ (bif b then a else a) = a
[PROOFSTEP]
cases b
[GOAL]
case false
α : Type u
a : α
⊢ (bif false then a else a) = a
[PROOFSTEP]
rfl
[GOAL]
case true
α : Type u
a : α
⊢ (bif true then a else a) = a
[PROOFSTEP]
rfl
[GOAL]
b : Bool
⊢ xor b b = false
[PROOFSTEP]
cases b
[GOAL]
case false
⊢ xor false false = false
[PROOFSTEP]
simp
[GOAL]
case true
⊢ xor true true = false
[PROOFSTEP]
simp
[GOAL]
b : Bool
⊢ xor b true = !b
[PROOFSTEP]
cases b
[GOAL]
case false
⊢ xor false true = !false
[PROOFSTEP]
simp
[GOAL]
case true
⊢ xor true true = !true
[PROOFSTEP]
simp
[GOAL]
b : Bool
⊢ xor b false = b
[PROOFSTEP]
cases b
[GOAL]
case false
⊢ xor false false = false
[PROOFSTEP]
simp
[GOAL]
case true
⊢ xor true false = true
[PROOFSTEP]
simp
[GOAL]
b : Bool
⊢ xor true b = !b
[PROOFSTEP]
cases b
[GOAL]
case false
⊢ xor true false = !false
[PROOFSTEP]
simp
[GOAL]
case true
⊢ xor true true = !true
[PROOFSTEP]
simp
[GOAL]
b : Bool
⊢ xor false b = b
[PROOFSTEP]
cases b
[GOAL]
case false
⊢ xor false false = false
[PROOFSTEP]
simp
[GOAL]
case true
⊢ xor false true = true
[PROOFSTEP]
simp
[GOAL]
⊢ ¬true = false
[PROOFSTEP]
decide
[GOAL]
⊢ ¬false = true
[PROOFSTEP]
decide
[GOAL]
b : Bool
⊢ (¬b = true) = (b = false)
[PROOFSTEP]
simp
[GOAL]
b : Bool
⊢ (¬b = false) = (b = true)
[PROOFSTEP]
simp
[GOAL]
a b : Bool
⊢ ((a && b) = true) = (a = true ∧ b = true)
[PROOFSTEP]
simp
[GOAL]
a b : Bool
⊢ ((a || b) = true) = (a = true ∨ b = true)
[PROOFSTEP]
simp
[GOAL]
a : Bool
⊢ ((!a) = true) = (a = false)
[PROOFSTEP]
cases a
[GOAL]
case false
⊢ ((!false) = true) = (false = false)
[PROOFSTEP]
simp
[GOAL]
case true
⊢ ((!true) = true) = (true = false)
[PROOFSTEP]
simp
[GOAL]
a b : Bool
⊢ ((a && b) = false) = (a = false ∨ b = false)
[PROOFSTEP]
cases a
[GOAL]
case false
b : Bool
⊢ ((false && b) = false) = (false = false ∨ b = false)
[PROOFSTEP]
cases b
[GOAL]
case true
b : Bool
⊢ ((true && b) = false) = (true = false ∨ b = false)
[PROOFSTEP]
cases b
[GOAL]
case false.false
⊢ ((false && false) = false) = (false = false ∨ false = false)
[PROOFSTEP]
simp
[GOAL]
case false.true
⊢ ((false && true) = false) = (false = false ∨ true = false)
[PROOFSTEP]
simp
[GOAL]
case true.false
⊢ ((true && false) = false) = (true = false ∨ false = false)
[PROOFSTEP]
simp
[GOAL]
case true.true
⊢ ((true && true) = false) = (true = false ∨ true = false)
[PROOFSTEP]
simp
[GOAL]
a b : Bool
⊢ ((a || b) = false) = (a = false ∧ b = false)
[PROOFSTEP]
cases a
[GOAL]
case false
b : Bool
⊢ ((false || b) = false) = (false = false ∧ b = false)
[PROOFSTEP]
cases b
[GOAL]
case true
b : Bool
⊢ ((true || b) = false) = (true = false ∧ b = false)
[PROOFSTEP]
cases b
[GOAL]
case false.false
⊢ ((false || false) = false) = (false = false ∧ false = false)
[PROOFSTEP]
simp
[GOAL]
case false.true
⊢ ((false || true) = false) = (false = false ∧ true = false)
[PROOFSTEP]
simp
[GOAL]
case true.false
⊢ ((true || false) = false) = (true = false ∧ false = false)
[PROOFSTEP]
simp
[GOAL]
case true.true
⊢ ((true || true) = false) = (true = false ∧ true = false)
[PROOFSTEP]
simp
[GOAL]
a : Bool
⊢ ((!a) = false) = (a = true)
[PROOFSTEP]
cases a
[GOAL]
case false
⊢ ((!false) = false) = (false = true)
[PROOFSTEP]
simp
[GOAL]
case true
⊢ ((!true) = false) = (true = true)
[PROOFSTEP]
simp
[GOAL]
⊢ (false = true) = False
[PROOFSTEP]
simp
[GOAL]
⊢ (true = true) = True
[PROOFSTEP]
simp
[GOAL]
⊢ (false = true) = False
[PROOFSTEP]
simp
[GOAL]
⊢ (true = true) = True
[PROOFSTEP]
simp
[GOAL]
p : Prop
d : Decidable p
⊢ decide p = true ↔ p
[PROOFSTEP]
simp
[GOAL]
b : Bool
⊢ ¬b = true ↔ b = false
[PROOFSTEP]
cases b
[GOAL]
case false
⊢ ¬false = true ↔ false = false
[PROOFSTEP]
exact by decide
[GOAL]
⊢ ¬false = true ↔ false = false
[PROOFSTEP]
decide
[GOAL]
case true
⊢ ¬true = true ↔ true = false
[PROOFSTEP]
exact by decide
[GOAL]
⊢ ¬true = true ↔ true = false
[PROOFSTEP]
decide
[GOAL]
p q : Prop
inst✝¹ : Decidable p
inst✝ : Decidable q
h : p ↔ q
⊢ decide p = decide q
[PROOFSTEP]
cases h' : decide q with
| false => exact decide_false (mt h.1 <| of_decide_false h')
| true => exact decide_true (h.2 <| of_decide_true h')
[GOAL]
p q : Prop
inst✝¹ : Decidable p
inst✝ : Decidable q
h : p ↔ q
x✝ : Bool
h' : decide q = x✝
⊢ decide p = x✝
[PROOFSTEP]
cases h' : decide q with
| false => exact decide_false (mt h.1 <| of_decide_false h')
| true => exact decide_true (h.2 <| of_decide_true h')
[GOAL]
case false
p q : Prop
inst✝¹ : Decidable p
inst✝ : Decidable q
h : p ↔ q
h' : decide q = false
⊢ decide p = false
[PROOFSTEP]

| false => exact decide_false (mt h.1 <| of_decide_false h')
[GOAL]
case false
p q : Prop
inst✝¹ : Decidable p
inst✝ : Decidable q
h : p ↔ q
h' : decide q = false
⊢ decide p = false
[PROOFSTEP]
exact decide_false (mt h.1 <| of_decide_false h')
[GOAL]
case true
p q : Prop
inst✝¹ : Decidable p
inst✝ : Decidable q
h : p ↔ q
h' : decide q = true
⊢ decide p = true
[PROOFSTEP]

| true => exact decide_true (h.2 <| of_decide_true h')
[GOAL]
case true
p q : Prop
inst✝¹ : Decidable p
inst✝ : Decidable q
h : p ↔ q
h' : decide q = true
⊢ decide p = true
[PROOFSTEP]
exact decide_true (h.2 <| of_decide_true h')
[GOAL]
a b : Bool
⊢ (a || b) = true ↔ a = true ∨ b = true
[PROOFSTEP]
simp
[GOAL]
a b : Bool
⊢ (a && b) = true ↔ a = true ∧ b = true
[PROOFSTEP]
simp
[GOAL]
a b : Bool
⊢ xor a b = true ↔ Xor' (a = true) (b = true)
[PROOFSTEP]
cases a
[GOAL]
case false
b : Bool
⊢ xor false b = true ↔ Xor' (false = true) (b = true)
[PROOFSTEP]
cases b
[GOAL]
case true
b : Bool
⊢ xor true b = true ↔ Xor' (true = true) (b = true)
[PROOFSTEP]
cases b
[GOAL]
case false.false
⊢ xor false false = true ↔ Xor' (false = true) (false = true)
[PROOFSTEP]
exact by decide
[GOAL]
⊢ xor false false = true ↔ Xor' (false = true) (false = true)
[PROOFSTEP]
decide
[GOAL]
case false.true
⊢ xor false true = true ↔ Xor' (false = true) (true = true)
[PROOFSTEP]
exact by decide
[GOAL]
⊢ xor false true = true ↔ Xor' (false = true) (true = true)
[PROOFSTEP]
decide
[GOAL]
case true.false
⊢ xor true false = true ↔ Xor' (true = true) (false = true)
[PROOFSTEP]
exact by decide
[GOAL]
⊢ xor true false = true ↔ Xor' (true = true) (false = true)
[PROOFSTEP]
decide
[GOAL]
case true.true
⊢ xor true true = true ↔ Xor' (true = true) (true = true)
[PROOFSTEP]
exact by decide
[GOAL]
⊢ xor true true = true ↔ Xor' (true = true) (true = true)
[PROOFSTEP]
decide
[GOAL]
c : Prop
inst✝ : Decidable c
a b : Bool
⊢ ((if c then a else b) = true) = if c then a = true else b = true
[PROOFSTEP]
by_cases c
[GOAL]
c : Prop
inst✝ : Decidable c
a b : Bool
⊢ ((if c then a else b) = true) = if c then a = true else b = true
[PROOFSTEP]
by_cases c
[GOAL]
case pos
c : Prop
inst✝ : Decidable c
a b : Bool
h : c
⊢ ((if c then a else b) = true) = if c then a = true else b = true
[PROOFSTEP]
simp [*]
[GOAL]
case neg
c : Prop
inst✝ : Decidable c
a b : Bool
h : ¬c
⊢ ((if c then a else b) = true) = if c then a = true else b = true
[PROOFSTEP]
simp [*]
[GOAL]
c : Prop
inst✝ : Decidable c
a b : Bool
⊢ ((if c then a else b) = false) = if c then a = false else b = false
[PROOFSTEP]
by_cases c
[GOAL]
c : Prop
inst✝ : Decidable c
a b : Bool
⊢ ((if c then a else b) = false) = if c then a = false else b = false
[PROOFSTEP]
by_cases c
[GOAL]
case pos
c : Prop
inst✝ : Decidable c
a b : Bool
h : c
⊢ ((if c then a else b) = false) = if c then a = false else b = false
[PROOFSTEP]
simp [*]
[GOAL]
case neg
c : Prop
inst✝ : Decidable c
a b : Bool
h : ¬c
⊢ ((if c then a else b) = false) = if c then a = false else b = false
[PROOFSTEP]
simp [*]


[GOAL]
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
l : List R
⊢ trop (sum l) = prod (map trop l)
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
⊢ trop (sum []) = prod (map trop [])
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
hd : R
tl : List R
IH : trop (sum tl) = prod (map trop tl)
⊢ trop (sum (hd :: tl)) = prod (map trop (hd :: tl))
[PROOFSTEP]
simp [← IH]
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Multiset R
⊢ ∀ (a : List R), trop (sum (Quotient.mk (List.isSetoid R) a)) = prod (map trop (Quotient.mk (List.isSetoid R) a))
[PROOFSTEP]
simpa using List.trop_sum
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → R
⊢ trop (∑ i in s, f i) = ∏ i in s, trop (f i)
[PROOFSTEP]
convert Multiset.trop_sum (s.val.map f)
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → R
⊢ ∏ i in s, trop (f i) = Multiset.prod (Multiset.map trop (Multiset.map f s.val))
[PROOFSTEP]
simp only [Multiset.map_map, Function.comp_apply]
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → R
⊢ ∏ i in s, trop (f i) = Multiset.prod (Multiset.map (fun i => trop (f i)) s.val)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
l : List (Tropical R)
⊢ untrop (prod l) = sum (map untrop l)
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
⊢ untrop (prod []) = sum (map untrop [])
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
hd : Tropical R
tl : List (Tropical R)
IH : untrop (prod tl) = sum (map untrop tl)
⊢ untrop (prod (hd :: tl)) = sum (map untrop (hd :: tl))
[PROOFSTEP]
simp [← IH]
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Multiset (Tropical R)
⊢ ∀ (a : List (Tropical R)),
    untrop (prod (Quotient.mk (List.isSetoid (Tropical R)) a)) =
      sum (map untrop (Quotient.mk (List.isSetoid (Tropical R)) a))
[PROOFSTEP]
simpa using List.untrop_prod
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → Tropical R
⊢ untrop (∏ i in s, f i) = ∑ i in s, untrop (f i)
[PROOFSTEP]
convert Multiset.untrop_prod (s.val.map f)
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → Tropical R
⊢ ∑ i in s, untrop (f i) = Multiset.sum (Multiset.map untrop (Multiset.map f s.val))
[PROOFSTEP]
simp only [Multiset.map_map, Function.comp_apply]
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → Tropical R
⊢ ∑ i in s, untrop (f i) = Multiset.sum (Multiset.map (fun i => untrop (f i)) s.val)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : LinearOrder R
l : List R
⊢ trop (minimum l) = sum (map (trop ∘ WithTop.some) l)
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
R : Type u_1
S : Type u_2
inst✝ : LinearOrder R
⊢ trop (minimum []) = sum (map (trop ∘ WithTop.some) [])
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u_1
S : Type u_2
inst✝ : LinearOrder R
hd : R
tl : List R
IH : trop (minimum tl) = sum (map (trop ∘ WithTop.some) tl)
⊢ trop (minimum (hd :: tl)) = sum (map (trop ∘ WithTop.some) (hd :: tl))
[PROOFSTEP]
simp [List.minimum_cons, ← IH]
[GOAL]
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Multiset R
⊢ trop (inf s) = sum (map trop s)
[PROOFSTEP]
induction' s using Multiset.induction with s x IH
[GOAL]
case empty
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
⊢ trop (inf 0) = sum (map trop 0)
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : R
x : Multiset R
IH : trop (inf x) = sum (map trop x)
⊢ trop (inf (s ::ₘ x)) = sum (map trop (s ::ₘ x))
[PROOFSTEP]
simp [← IH]
[GOAL]
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Finset S
f : S → R
⊢ trop (inf s f) = ∑ i in s, trop (f i)
[PROOFSTEP]
convert Multiset.trop_inf (s.val.map f)
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Finset S
f : S → R
⊢ ∑ i in s, trop (f i) = Multiset.sum (Multiset.map trop (Multiset.map f s.val))
[PROOFSTEP]
simp only [Multiset.map_map, Function.comp_apply]
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Finset S
f : S → R
⊢ ∑ i in s, trop (f i) = Multiset.sum (Multiset.map (fun i => trop (f i)) s.val)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : ConditionallyCompleteLinearOrder R
s : Finset S
f : S → WithTop R
⊢ trop (sInf (f '' ↑s)) = ∑ i in s, trop (f i)
[PROOFSTEP]
rcases s.eq_empty_or_nonempty with (rfl | h)
[GOAL]
case inl
R : Type u_1
S : Type u_2
inst✝ : ConditionallyCompleteLinearOrder R
f : S → WithTop R
⊢ trop (sInf (f '' ↑∅)) = ∑ i in ∅, trop (f i)
[PROOFSTEP]
simp only [Set.image_empty, coe_empty, sum_empty, WithTop.sInf_empty, trop_top]
[GOAL]
case inr
R : Type u_1
S : Type u_2
inst✝ : ConditionallyCompleteLinearOrder R
s : Finset S
f : S → WithTop R
h : Finset.Nonempty s
⊢ trop (sInf (f '' ↑s)) = ∑ i in s, trop (f i)
[PROOFSTEP]
rw [← inf'_eq_csInf_image _ h, inf'_eq_inf, s.trop_inf]
[GOAL]
R : Type u_1
S : Type u_2
inst✝¹ : ConditionallyCompleteLinearOrder R
inst✝ : Fintype S
f : S → WithTop R
⊢ trop (⨅ (i : S), f i) = ∑ i : S, trop (f i)
[PROOFSTEP]
rw [iInf, ← Set.image_univ, ← coe_univ, trop_sInf_image]
[GOAL]
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Multiset (Tropical R)
⊢ untrop (sum s) = inf (map untrop s)
[PROOFSTEP]
induction' s using Multiset.induction with s x IH
[GOAL]
case empty
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
⊢ untrop (sum 0) = inf (map untrop 0)
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Tropical R
x : Multiset (Tropical R)
IH : untrop (sum x) = inf (map untrop x)
⊢ untrop (sum (s ::ₘ x)) = inf (map untrop (s ::ₘ x))
[PROOFSTEP]
simp only [sum_cons, ge_iff_le, untrop_add, untrop_le_iff, map_cons, inf_cons, ← IH]
[GOAL]
case cons
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Tropical R
x : Multiset (Tropical R)
IH : untrop (sum x) = inf (map untrop x)
⊢ min (untrop s) (untrop (sum x)) = untrop s ⊓ untrop (sum x)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Finset S
f : S → Tropical R
⊢ untrop (∑ i in s, f i) = inf s (untrop ∘ f)
[PROOFSTEP]
convert Multiset.untrop_sum (s.val.map f)
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Finset S
f : S → Tropical R
⊢ inf s (untrop ∘ f) = Multiset.inf (Multiset.map untrop (Multiset.map f s.val))
[PROOFSTEP]
simp only [Multiset.map_map, Function.comp_apply]
[GOAL]
case h.e'_3
R : Type u_1
S : Type u_2
inst✝¹ : LinearOrder R
inst✝ : OrderTop R
s : Finset S
f : S → Tropical R
⊢ inf s (untrop ∘ f) = Multiset.inf (Multiset.map (fun x => untrop (f x)) s.val)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : ConditionallyCompleteLinearOrder R
s : Finset S
f : S → Tropical (WithTop R)
⊢ untrop (∑ i in s, f i) = sInf (untrop ∘ f '' ↑s)
[PROOFSTEP]
rcases s.eq_empty_or_nonempty with (rfl | h)
[GOAL]
case inl
R : Type u_1
S : Type u_2
inst✝ : ConditionallyCompleteLinearOrder R
f : S → Tropical (WithTop R)
⊢ untrop (∑ i in ∅, f i) = sInf (untrop ∘ f '' ↑∅)
[PROOFSTEP]
simp only [Set.image_empty, coe_empty, sum_empty, WithTop.sInf_empty, untrop_zero]
[GOAL]
case inr
R : Type u_1
S : Type u_2
inst✝ : ConditionallyCompleteLinearOrder R
s : Finset S
f : S → Tropical (WithTop R)
h : Finset.Nonempty s
⊢ untrop (∑ i in s, f i) = sInf (untrop ∘ f '' ↑s)
[PROOFSTEP]
rw [← inf'_eq_csInf_image _ h, inf'_eq_inf, Finset.untrop_sum']
[GOAL]
R : Type u_1
S : Type u_2
inst✝¹ : ConditionallyCompleteLinearOrder R
inst✝ : Fintype S
f : S → Tropical (WithTop R)
⊢ untrop (∑ i : S, f i) = ⨅ (i : S), untrop (f i)
[PROOFSTEP]
rw [iInf, ← Set.image_univ, ← coe_univ, untrop_sum_eq_sInf_image]
[GOAL]
R : Type u_1
S : Type u_2
inst✝¹ : ConditionallyCompleteLinearOrder R
inst✝ : Fintype S
f : S → Tropical (WithTop R)
⊢ sInf ((untrop ∘ fun i => f i) '' ↑univ) = sInf ((fun i => untrop (f i)) '' ↑univ)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
inst✝ : ConditionallyCompleteLinearOrder R
s : Finset S
f : S → Tropical (WithTop R)
⊢ untrop (∑ i in s, f i) = ⨅ (i : { x // x ∈ s }), untrop (f ↑i)
[PROOFSTEP]
simpa [← _root_.untrop_sum] using sum_attach.symm