l3lab/ntp-mathlib huggingface dataset:
/-- Let `B : PowerBasis S A` be such that `IsIntegral R B.gen`, and let `x : A` be an element
with integral coordinates in the base `B.basis`. Then `IsIntegral R ((B.basis.repr (x ^ n) i)` for
all `i` and all `n` if `minpoly S B.gen = (minpoly R B.gen).map (algebraMap R S)`. This is the case
if `R` is a GCD domain and `S` is its fraction ring. -/
theorem repr_pow_isIntegral [IsDomain S] {x : A} (hx : ∀ i, IsIntegral R (B.basis.repr x i))
    (hmin : minpoly S B.gen = (minpoly R B.gen).map (algebraMap R S)) (n : ℕ) :
    ∀ i, IsIntegral R (B.basis.repr (x ^ n) i) := by
  nontriviality A using Subsingleton.elim (x ^ n) 0, isIntegral_zero
  revert hx
  refine' Nat.case_strong_induction_on
    -- Porting note: had to hint what to induct on
    (p := fun n ↦ _ → ∀ (i : Fin B.dim), IsIntegral R (B.basis.repr (x ^ n) i))
    n _ fun n hn => _
  · intro _ i
    rw [pow_zero, ← pow_zero B.gen, ← Fin.val_mk B.dim_pos, ← B.basis_eq_pow,
      B.basis.repr_self_apply]
    split_ifs
    · exact isIntegral_one
    · exact isIntegral_zero
  · intro hx
    rw [pow_succ]
    

Proof state:
case refine'_2
K : Type u_1
S : Type u_2
inst✝¹¹ : Field K
inst✝¹⁰ : CommRing S
inst✝⁹ : Algebra K S
R : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : Algebra R S
inst✝⁶ : Algebra R K
inst✝⁵ : IsScalarTower R K S
A : Type u_4
inst✝⁴ : CommRing A
inst✝³ : Algebra R A
inst✝² : Algebra S A
inst✝¹ : IsScalarTower R S A
B : PowerBasis S A
hB : IsIntegral R B.gen
inst✝ : IsDomain S
x : A
hmin : minpoly S B.gen = Polynomial.map (algebraMap R S) (minpoly R B.gen)
n✝ : ℕ
✝ : Nontrivial A
n : ℕ
hn :
  ∀ m ≤ n,
    (fun n =>
        (∀ (i : Fin B.dim), IsIntegral R ((B.basis.repr x) i)) →
          ∀ (i : Fin B.dim), IsIntegral R ((B.basis.repr (x ^ n)) i))
      m
hx : ∀ (i : Fin B.dim), IsIntegral R ((B.basis.repr x) i)
⊢ ∀ (i : Fin B.dim), IsIntegral R ((B.basis.repr (x * x ^ n)) i)

Next tactic:
exact repr_mul_isIntegral hB hx (fun _ => hn _ le_rfl (fun _ => hx _) _) hmin
/-- Let `B B' : PowerBasis K S` be such that `IsIntegral R B.gen`, and let `P : R[X]` be such that
`aeval B.gen P = B'.gen`. Then `IsIntegral R (B.basis.to_matrix B'.basis i j)` for all `i` and `j`
if `minpoly K B.gen = (minpoly R B.gen).map (algebraMap R L)`. This is the case
if `R` is a GCD domain and `K` is its fraction ring. -/
theorem toMatrix_isIntegral {B B' : PowerBasis K S} {P : R[X]} (h : aeval B.gen P = B'.gen)
    (hB : IsIntegral R B.gen) (hmin : minpoly K B.gen = (minpoly R B.gen).map (algebraMap R K)) :
    ∀ i j, IsIntegral R (B.basis.toMatrix B'.basis i j) := by
  

Proof state:
K : Type u_1
S : Type u_2
inst✝¹⁰ : Field K
inst✝⁹ : CommRing S
inst✝⁸ : Algebra K S
R : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Algebra R S
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K S
A : Type u_4
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
B✝ : PowerBasis S A
hB✝ : IsIntegral R B✝.gen
B B' : PowerBasis K S
P : R[X]
h : (aeval B.gen) P = B'.gen
hB : IsIntegral R B.gen
hmin : minpoly K B.gen = Polynomial.map (algebraMap R K) (minpoly R B.gen)
⊢ ∀ (i : Fin B.dim) (j : Fin B'.dim), IsIntegral R (Basis.toMatrix B.basis (⇑B'.basis) i j)

Next tactic:
intro i j
/-- Let `B B' : PowerBasis K S` be such that `IsIntegral R B.gen`, and let `P : R[X]` be such that
`aeval B.gen P = B'.gen`. Then `IsIntegral R (B.basis.to_matrix B'.basis i j)` for all `i` and `j`
if `minpoly K B.gen = (minpoly R B.gen).map (algebraMap R L)`. This is the case
if `R` is a GCD domain and `K` is its fraction ring. -/
theorem toMatrix_isIntegral {B B' : PowerBasis K S} {P : R[X]} (h : aeval B.gen P = B'.gen)
    (hB : IsIntegral R B.gen) (hmin : minpoly K B.gen = (minpoly R B.gen).map (algebraMap R K)) :
    ∀ i j, IsIntegral R (B.basis.toMatrix B'.basis i j) := by
  intro i j
  

Proof state:
K : Type u_1
S : Type u_2
inst✝¹⁰ : Field K
inst✝⁹ : CommRing S
inst✝⁸ : Algebra K S
R : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Algebra R S
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K S
A : Type u_4
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
B✝ : PowerBasis S A
hB✝ : IsIntegral R B✝.gen
B B' : PowerBasis K S
P : R[X]
h : (aeval B.gen) P = B'.gen
hB : IsIntegral R B.gen
hmin : minpoly K B.gen = Polynomial.map (algebraMap R K) (minpoly R B.gen)
i : Fin B.dim
j : Fin B'.dim
⊢ IsIntegral R (Basis.toMatrix B.basis (⇑B'.basis) i j)

Next tactic:
rw [B.basis.toMatrix_apply, B'.coe_basis]
/-- Let `B B' : PowerBasis K S` be such that `IsIntegral R B.gen`, and let `P : R[X]` be such that
`aeval B.gen P = B'.gen`. Then `IsIntegral R (B.basis.to_matrix B'.basis i j)` for all `i` and `j`
if `minpoly K B.gen = (minpoly R B.gen).map (algebraMap R L)`. This is the case
if `R` is a GCD domain and `K` is its fraction ring. -/
theorem toMatrix_isIntegral {B B' : PowerBasis K S} {P : R[X]} (h : aeval B.gen P = B'.gen)
    (hB : IsIntegral R B.gen) (hmin : minpoly K B.gen = (minpoly R B.gen).map (algebraMap R K)) :
    ∀ i j, IsIntegral R (B.basis.toMatrix B'.basis i j) := by
  intro i j
  rw [B.basis.toMatrix_apply, B'.coe_basis]
  

Proof state:
K : Type u_1
S : Type u_2
inst✝¹⁰ : Field K
inst✝⁹ : CommRing S
inst✝⁸ : Algebra K S
R : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Algebra R S
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K S
A : Type u_4
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
B✝ : PowerBasis S A
hB✝ : IsIntegral R B✝.gen
B B' : PowerBasis K S
P : R[X]
h : (aeval B.gen) P = B'.gen
hB : IsIntegral R B.gen
hmin : minpoly K B.gen = Polynomial.map (algebraMap R K) (minpoly R B.gen)
i : Fin B.dim
j : Fin B'.dim
⊢ IsIntegral R ((B.basis.repr ((fun i => B'.gen ^ ↑i) j)) i)

Next tactic:
refine' repr_pow_isIntegral hB (fun i => _) hmin _ _
/-- Let `B B' : PowerBasis K S` be such that `IsIntegral R B.gen`, and let `P : R[X]` be such that
`aeval B.gen P = B'.gen`. Then `IsIntegral R (B.basis.to_matrix B'.basis i j)` for all `i` and `j`
if `minpoly K B.gen = (minpoly R B.gen).map (algebraMap R L)`. This is the case
if `R` is a GCD domain and `K` is its fraction ring. -/
theorem toMatrix_isIntegral {B B' : PowerBasis K S} {P : R[X]} (h : aeval B.gen P = B'.gen)
    (hB : IsIntegral R B.gen) (hmin : minpoly K B.gen = (minpoly R B.gen).map (algebraMap R K)) :
    ∀ i j, IsIntegral R (B.basis.toMatrix B'.basis i j) := by
  intro i j
  rw [B.basis.toMatrix_apply, B'.coe_basis]
  refine' repr_pow_isIntegral hB (fun i => _) hmin _ _
  

Proof state:
K : Type u_1
S : Type u_2
inst✝¹⁰ : Field K
inst✝⁹ : CommRing S
inst✝⁸ : Algebra K S
R : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Algebra R S
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K S
A : Type u_4
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
B✝ : PowerBasis S A
hB✝ : IsIntegral R B✝.gen
B B' : PowerBasis K S
P : R[X]
h : (aeval B.gen) P = B'.gen
hB : IsIntegral R B.gen
hmin : minpoly K B.gen = Polynomial.map (algebraMap R K) (minpoly R B.gen)
i✝ : Fin B.dim
j : Fin B'.dim
i : Fin B.dim
⊢ IsIntegral R ((B.basis.repr B'.gen) i)

Next tactic:
rw [← h, aeval_eq_sum_range, map_sum, Finset.sum_apply']
/-- Let `B B' : PowerBasis K S` be such that `IsIntegral R B.gen`, and let `P : R[X]` be such that
`aeval B.gen P = B'.gen`. Then `IsIntegral R (B.basis.to_matrix B'.basis i j)` for all `i` and `j`
if `minpoly K B.gen = (minpoly R B.gen).map (algebraMap R L)`. This is the case
if `R` is a GCD domain and `K` is its fraction ring. -/
theorem toMatrix_isIntegral {B B' : PowerBasis K S} {P : R[X]} (h : aeval B.gen P = B'.gen)
    (hB : IsIntegral R B.gen) (hmin : minpoly K B.gen = (minpoly R B.gen).map (algebraMap R K)) :
    ∀ i j, IsIntegral R (B.basis.toMatrix B'.basis i j) := by
  intro i j
  rw [B.basis.toMatrix_apply, B'.coe_basis]
  refine' repr_pow_isIntegral hB (fun i => _) hmin _ _
  rw [← h, aeval_eq_sum_range, map_sum, Finset.sum_apply']
  

Proof state:
K : Type u_1
S : Type u_2
inst✝¹⁰ : Field K
inst✝⁹ : CommRing S
inst✝⁸ : Algebra K S
R : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Algebra R S
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K S
A : Type u_4
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
B✝ : PowerBasis S A
hB✝ : IsIntegral R B✝.gen
B B' : PowerBasis K S
P : R[X]
h : (aeval B.gen) P = B'.gen
hB : IsIntegral R B.gen
hmin : minpoly K B.gen = Polynomial.map (algebraMap R K) (minpoly R B.gen)
i✝ : Fin B.dim
j : Fin B'.dim
i : Fin B.dim
⊢ IsIntegral R (Finset.sum (Finset.range (natDegree P + 1)) fun k => (B.basis.repr (coeff P k • B.gen ^ k)) i)

Next tactic:
refine' IsIntegral.sum _ fun n _ => _
/-- Let `B B' : PowerBasis K S` be such that `IsIntegral R B.gen`, and let `P : R[X]` be such that
`aeval B.gen P = B'.gen`. Then `IsIntegral R (B.basis.to_matrix B'.basis i j)` for all `i` and `j`
if `minpoly K B.gen = (minpoly R B.gen).map (algebraMap R L)`. This is the case
if `R` is a GCD domain and `K` is its fraction ring. -/
theorem toMatrix_isIntegral {B B' : PowerBasis K S} {P : R[X]} (h : aeval B.gen P = B'.gen)
    (hB : IsIntegral R B.gen) (hmin : minpoly K B.gen = (minpoly R B.gen).map (algebraMap R K)) :
    ∀ i j, IsIntegral R (B.basis.toMatrix B'.basis i j) := by
  intro i j
  rw [B.basis.toMatrix_apply, B'.coe_basis]
  refine' repr_pow_isIntegral hB (fun i => _) hmin _ _
  rw [← h, aeval_eq_sum_range, map_sum, Finset.sum_apply']
  refine' IsIntegral.sum _ fun n _ => _
  

Proof state:
K : Type u_1
S : Type u_2
inst✝¹⁰ : Field K
inst✝⁹ : CommRing S
inst✝⁸ : Algebra K S
R : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Algebra R S
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K S
A : Type u_4
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
B✝ : PowerBasis S A
hB✝ : IsIntegral R B✝.gen
B B' : PowerBasis K S
P : R[X]
h : (aeval B.gen) P = B'.gen
hB : IsIntegral R B.gen
hmin : minpoly K B.gen = Polynomial.map (algebraMap R K) (minpoly R B.gen)
i✝ : Fin B.dim
j : Fin B'.dim
i : Fin B.dim
n : ℕ
x✝ : n ∈ Finset.range (natDegree P + 1)
⊢ IsIntegral R ((B.basis.repr (coeff P n • B.gen ^ n)) i)

Next tactic:
rw [Algebra.smul_def, IsScalarTower.algebraMap_apply R K S, ← Algebra.smul_def,
    LinearEquiv.map_smul, algebraMap_smul]
/-- Let `B B' : PowerBasis K S` be such that `IsIntegral R B.gen`, and let `P : R[X]` be such that
`aeval B.gen P = B'.gen`. Then `IsIntegral R (B.basis.to_matrix B'.basis i j)` for all `i` and `j`
if `minpoly K B.gen = (minpoly R B.gen).map (algebraMap R L)`. This is the case
if `R` is a GCD domain and `K` is its fraction ring. -/
theorem toMatrix_isIntegral {B B' : PowerBasis K S} {P : R[X]} (h : aeval B.gen P = B'.gen)
    (hB : IsIntegral R B.gen) (hmin : minpoly K B.gen = (minpoly R B.gen).map (algebraMap R K)) :
    ∀ i j, IsIntegral R (B.basis.toMatrix B'.basis i j) := by
  intro i j
  rw [B.basis.toMatrix_apply, B'.coe_basis]
  refine' repr_pow_isIntegral hB (fun i => _) hmin _ _
  rw [← h, aeval_eq_sum_range, map_sum, Finset.sum_apply']
  refine' IsIntegral.sum _ fun n _ => _
  rw [Algebra.smul_def, IsScalarTower.algebraMap_apply R K S, ← Algebra.smul_def,
    LinearEquiv.map_smul, algebraMap_smul]
  

Proof state:
K : Type u_1
S : Type u_2
inst✝¹⁰ : Field K
inst✝⁹ : CommRing S
inst✝⁸ : Algebra K S
R : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Algebra R S
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K S
A : Type u_4
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
B✝ : PowerBasis S A
hB✝ : IsIntegral R B✝.gen
B B' : PowerBasis K S
P : R[X]
h : (aeval B.gen) P = B'.gen
hB : IsIntegral R B.gen
hmin : minpoly K B.gen = Polynomial.map (algebraMap R K) (minpoly R B.gen)
i✝ : Fin B.dim
j : Fin B'.dim
i : Fin B.dim
n : ℕ
x✝ : n ∈ Finset.range (natDegree P + 1)
⊢ IsIntegral R ((coeff P n • B.basis.repr (B.gen ^ n)) i)

Next tactic:
exact (repr_gen_pow_isIntegral hB hmin _ _).smul _
/-- A copy of `invOf_mul_self_assoc` for rectangular matrices. -/
protected theorem invOf_mul_self_assoc (A : Matrix n n α) (B : Matrix n m α) [Invertible A] :
    ⅟ A * (A * B) = B := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : Semiring α
A : Matrix n n α
B : Matrix n m α
inst✝ : Invertible A
⊢ ⅟A * (A * B) = B

Next tactic:
rw [← Matrix.mul_assoc, invOf_mul_self, Matrix.one_mul]
/-- A copy of `mul_invOf_self_assoc` for rectangular matrices. -/
protected theorem mul_invOf_self_assoc (A : Matrix n n α) (B : Matrix n m α) [Invertible A] :
    A * (⅟ A * B) = B := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : Semiring α
A : Matrix n n α
B : Matrix n m α
inst✝ : Invertible A
⊢ A * (⅟A * B) = B

Next tactic:
rw [← Matrix.mul_assoc, mul_invOf_self, Matrix.one_mul]
/-- A copy of `mul_invOf_mul_self_cancel` for rectangular matrices. -/
protected theorem mul_invOf_mul_self_cancel (A : Matrix m n α) (B : Matrix n n α) [Invertible B] :
    A * ⅟ B * B = A := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : Semiring α
A : Matrix m n α
B : Matrix n n α
inst✝ : Invertible B
⊢ A * ⅟B * B = A

Next tactic:
rw [Matrix.mul_assoc, invOf_mul_self, Matrix.mul_one]
/-- A copy of `mul_mul_invOf_self_cancel` for rectangular matrices. -/
protected theorem mul_mul_invOf_self_cancel (A : Matrix m n α) (B : Matrix n n α) [Invertible B] :
    A * B * ⅟ B = A := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : Semiring α
A : Matrix m n α
B : Matrix n n α
inst✝ : Invertible B
⊢ A * B * ⅟B = A

Next tactic:
rw [Matrix.mul_assoc, mul_invOf_self, Matrix.mul_one]
/-- A matrix is invertible if the conjugate transpose is invertible. -/
def invertibleOfInvertibleConjTranspose [Invertible Aᴴ] : Invertible A := by
  

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : Semiring α
inst✝¹ : StarRing α
A : Matrix n n α
inst✝ : Invertible Aᴴ
⊢ Invertible A

Next tactic:
rw [← conjTranspose_conjTranspose A, ← star_eq_conjTranspose]
/-- A matrix is invertible if the conjugate transpose is invertible. -/
def invertibleOfInvertibleConjTranspose [Invertible Aᴴ] : Invertible A := by
  rw [← conjTranspose_conjTranspose A, ← star_eq_conjTranspose]
  

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : Semiring α
inst✝¹ : StarRing α
A : Matrix n n α
inst✝ : Invertible Aᴴ
⊢ Invertible (star Aᴴ)

Next tactic:
infer_instance
/-- The transpose of an invertible matrix is invertible. -/
instance invertibleTranspose [Invertible A] : Invertible Aᵀ where
  invOf := (⅟A)ᵀ
  invOf_mul_self := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommSemiring α
A : Matrix n n α
inst✝ : Invertible A
⊢ (⅟A)ᵀ * Aᵀ = 1

Next tactic:
rw [← transpose_mul, mul_invOf_self, transpose_one]
/-- The transpose of an invertible matrix is invertible. -/
instance invertibleTranspose [Invertible A] : Invertible Aᵀ where
  invOf := (⅟A)ᵀ
  invOf_mul_self := by rw [← transpose_mul, mul_invOf_self, transpose_one]
  mul_invOf_self := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommSemiring α
A : Matrix n n α
inst✝ : Invertible A
⊢ Aᵀ * (⅟A)ᵀ = 1

Next tactic:
rw [← transpose_mul, invOf_mul_self, transpose_one]
lemma transpose_invOf [Invertible A] [Invertible Aᵀ] : (⅟A)ᵀ = ⅟(Aᵀ) := by
  

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommSemiring α
A : Matrix n n α
inst✝¹ : Invertible A
inst✝ : Invertible Aᵀ
⊢ (⅟A)ᵀ = ⅟Aᵀ

Next tactic:
letI := invertibleTranspose A
lemma transpose_invOf [Invertible A] [Invertible Aᵀ] : (⅟A)ᵀ = ⅟(Aᵀ) := by
  letI := invertibleTranspose A
  

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝⁴ : Fintype n
inst✝³ : DecidableEq n
inst✝² : CommSemiring α
A : Matrix n n α
inst✝¹ : Invertible A
inst✝ : Invertible Aᵀ
this : Invertible Aᵀ := invertibleTranspose A
⊢ (⅟A)ᵀ = ⅟Aᵀ

Next tactic:
convert (rfl : _ = ⅟(Aᵀ))
/-- `Aᵀ` is invertible when `A` is. -/
def invertibleOfInvertibleTranspose [Invertible Aᵀ] : Invertible A where
  invOf := (⅟(Aᵀ))ᵀ
  invOf_mul_self := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommSemiring α
A : Matrix n n α
inst✝ : Invertible Aᵀ
⊢ (⅟Aᵀ)ᵀ * A = 1

Next tactic:
rw [← transpose_one, ← mul_invOf_self Aᵀ, transpose_mul, transpose_transpose]
/-- `Aᵀ` is invertible when `A` is. -/
def invertibleOfInvertibleTranspose [Invertible Aᵀ] : Invertible A where
  invOf := (⅟(Aᵀ))ᵀ
  invOf_mul_self := by rw [← transpose_one, ← mul_invOf_self Aᵀ, transpose_mul, transpose_transpose]
  mul_invOf_self := by 

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝³ : Fintype n
inst✝² : DecidableEq n
inst✝¹ : CommSemiring α
A : Matrix n n α
inst✝ : Invertible Aᵀ
⊢ A * (⅟Aᵀ)ᵀ = 1

Next tactic:
rw [← transpose_one, ← invOf_mul_self Aᵀ, transpose_mul, transpose_transpose]
@[simp] lemma isUnit_transpose : IsUnit Aᵀ ↔ IsUnit A := by
  

Proof state:
m : Type u_1
n : Type u_2
α : Type u_3
inst✝² : Fintype n
inst✝¹ : DecidableEq n
inst✝ : CommSemiring α
A : Matrix n n α
⊢ IsUnit Aᵀ ↔ IsUnit A

Next tactic:
simp only [← nonempty_invertible_iff_isUnit,
    (transposeInvertibleEquivInvertible A).nonempty_congr]
/-- The algebra structure which will be the apex of the new limit cone for `D`. -/
@[simps]
def conePoint : Algebra T where
  A := c.pt
  a := t.lift (newCone D c)
  unit :=
    t.hom_ext fun j => by
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
j : J
⊢ ((η T).app c.pt ≫ IsLimit.lift t (newCone D c)) ≫ c.π.app j = 𝟙 c.pt ≫ c.π.app j

Next tactic:
rw [Category.assoc, t.fac, newCone_π_app, ← T.η.naturality_assoc, Functor.id_map,
        (D.obj j).unit]
/-- The algebra structure which will be the apex of the new limit cone for `D`. -/
@[simps]
def conePoint : Algebra T where
  A := c.pt
  a := t.lift (newCone D c)
  unit :=
    t.hom_ext fun j => by
      rw [Category.assoc, t.fac, newCone_π_app, ← T.η.naturality_assoc, Functor.id_map,
        (D.obj j).unit]
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
j : J
⊢ c.π.app j ≫ 𝟙 (D.obj j).A = 𝟙 c.pt ≫ c.π.app j

Next tactic:
dsimp
/-- The algebra structure which will be the apex of the new limit cone for `D`. -/
@[simps]
def conePoint : Algebra T where
  A := c.pt
  a := t.lift (newCone D c)
  unit :=
    t.hom_ext fun j => by
      rw [Category.assoc, t.fac, newCone_π_app, ← T.η.naturality_assoc, Functor.id_map,
        (D.obj j).unit]
      dsimp; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
j : J
⊢ c.π.app j ≫ 𝟙 (D.obj j).A = 𝟙 c.pt ≫ c.π.app j

Next tactic:
simp
/-- The algebra structure which will be the apex of the new limit cone for `D`. -/
@[simps]
def conePoint : Algebra T where
  A := c.pt
  a := t.lift (newCone D c)
  unit :=
    t.hom_ext fun j => by
      rw [Category.assoc, t.fac, newCone_π_app, ← T.η.naturality_assoc, Functor.id_map,
        (D.obj j).unit]
      dsimp; simp
  -- See library note [dsimp, simp]
  assoc :=
    t.hom_ext fun j => by
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
j : J
⊢ ((μ T).app c.pt ≫ IsLimit.lift t (newCone D c)) ≫ c.π.app j =
    (T.map (IsLimit.lift t (newCone D c)) ≫ IsLimit.lift t (newCone D c)) ≫ c.π.app j

Next tactic:
rw [Category.assoc, Category.assoc, t.fac (newCone D c), newCone_π_app, ←
        Functor.map_comp_assoc, t.fac (newCone D c), newCone_π_app, ← T.μ.naturality_assoc,
        (D.obj j).assoc, Functor.map_comp, Category.assoc]
/-- The algebra structure which will be the apex of the new limit cone for `D`. -/
@[simps]
def conePoint : Algebra T where
  A := c.pt
  a := t.lift (newCone D c)
  unit :=
    t.hom_ext fun j => by
      rw [Category.assoc, t.fac, newCone_π_app, ← T.η.naturality_assoc, Functor.id_map,
        (D.obj j).unit]
      dsimp; simp
  -- See library note [dsimp, simp]
  assoc :=
    t.hom_ext fun j => by
      rw [Category.assoc, Category.assoc, t.fac (newCone D c), newCone_π_app, ←
        Functor.map_comp_assoc, t.fac (newCone D c), newCone_π_app, ← T.μ.naturality_assoc,
        (D.obj j).assoc, Functor.map_comp, Category.assoc]
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
j : J
⊢ (T.toFunctor ⋙ T.toFunctor).map (c.π.app j) ≫ T.map (D.obj j).a ≫ (D.obj j).a =
    T.map (T.map (c.π.app j)) ≫ T.map (D.obj j).a ≫ (D.obj j).a

Next tactic:
rfl
/-- (Impl) Construct the lifted cone in `Algebra T` which will be limiting. -/
@[simps]
def liftedCone : Cone D where
  pt := conePoint D c t
  π :=
    { app := fun j => { f := c.π.app j }
      naturality := fun X Y f => by
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
X Y : J
f : X ⟶ Y
⊢ ((Functor.const J).obj (conePoint D c t)).map f ≫ (fun j => Algebra.Hom.mk (c.π.app j)) Y =
    (fun j => Algebra.Hom.mk (c.π.app j)) X ≫ D.map f

Next tactic:
ext1
/-- (Impl) Construct the lifted cone in `Algebra T` which will be limiting. -/
@[simps]
def liftedCone : Cone D where
  pt := conePoint D c t
  π :=
    { app := fun j => { f := c.π.app j }
      naturality := fun X Y f => by
        ext1
        

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
X Y : J
f : X ⟶ Y
⊢ (((Functor.const J).obj (conePoint D c t)).map f ≫ (fun j => Algebra.Hom.mk (c.π.app j)) Y).f =
    ((fun j => Algebra.Hom.mk (c.π.app j)) X ≫ D.map f).f

Next tactic:
dsimp
/-- (Impl) Construct the lifted cone in `Algebra T` which will be limiting. -/
@[simps]
def liftedCone : Cone D where
  pt := conePoint D c t
  π :=
    { app := fun j => { f := c.π.app j }
      naturality := fun X Y f => by
        ext1
        dsimp
        

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
X Y : J
f : X ⟶ Y
⊢ 𝟙 c.pt ≫ c.π.app Y = c.π.app X ≫ (D.map f).f

Next tactic:
erw [c.w f]
/-- (Impl) Construct the lifted cone in `Algebra T` which will be limiting. -/
@[simps]
def liftedCone : Cone D where
  pt := conePoint D c t
  π :=
    { app := fun j => { f := c.π.app j }
      naturality := fun X Y f => by
        ext1
        dsimp
        erw [c.w f]
        

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
X Y : J
f : X ⟶ Y
⊢ 𝟙 c.pt ≫ c.π.app Y = c.π.app Y

Next tactic:
simp
/-- (Impl) Prove that the lifted cone is limiting. -/
@[simps]
def liftedConeIsLimit : IsLimit (liftedCone D c t) where
  lift s :=
    { f := t.lift ((forget T).mapCone s)
      h :=
        t.hom_ext fun j => by
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
T : Monad C
J : Type u
inst✝ : Category.{v, u} J
D : J ⥤ Algebra T
c : Cone (D ⋙ forget T)
t : IsLimit c
s : Cone D
j : J
⊢ (T.map (IsLimit.lift t ((forget T).mapCone s)) ≫ (liftedCone D c t).pt.a) ≫ c.π.app j =
    (s.pt.a ≫ IsLimit.lift t ((forget T).mapCone s)) ≫ c.π.app j

Next tactic:
dsimp