l3lab/ntp-mathlib huggingface dataset:
/-- Matrices over dual numbers and dual numbers over matrices are isomorphic. -/
@[simps]
def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Matrix n n R) where
  toFun A := ⟨of fun i j => (A i j).fst, of fun i j => (A i j).snd⟩
  invFun d := of fun i j => (d.fst i j, d.snd i j)
  left_inv A := Matrix.ext fun i j => TrivSqZeroExt.ext rfl rfl
  right_inv d := TrivSqZeroExt.ext (Matrix.ext fun i j => rfl) (Matrix.ext fun i j => rfl)
  map_mul' A B := by
    ext
    · dsimp [mul_apply]
      simp_rw [fst_sum]
      rfl
    · 

Proof state:
case h2.a.h
R n : Type
inst✝² : CommSemiring R
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A B : Matrix n n (DualNumber R)
i✝ x✝ : n
⊢ snd
      (Equiv.toFun
        { toFun := fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)),
          invFun := fun d => of fun i j => (fst d i j, snd d i j),
          left_inv :=
            (_ :
              ∀ (A : Matrix n n (DualNumber R)),
                (fun d => of fun i j => (fst d i j, snd d i j))
                    ((fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j))) A) =
                  A),
          right_inv :=
            (_ :
              ∀ (d : DualNumber (Matrix n n R)),
                (fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)))
                    ((fun d => of fun i j => (fst d i j, snd d i j)) d) =
                  d) }
        (A * B))
      i✝ x✝ =
    snd
      (Equiv.toFun
          { toFun := fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)),
            invFun := fun d => of fun i j => (fst d i j, snd d i j),
            left_inv :=
              (_ :
                ∀ (A : Matrix n n (DualNumber R)),
                  (fun d => of fun i j => (fst d i j, snd d i j))
                      ((fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j))) A) =
                    A),
            right_inv :=
              (_ :
                ∀ (d : DualNumber (Matrix n n R)),
                  (fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)))
                      ((fun d => of fun i j => (fst d i j, snd d i j)) d) =
                    d) }
          A *
        Equiv.toFun
          { toFun := fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)),
            invFun := fun d => of fun i j => (fst d i j, snd d i j),
            left_inv :=
              (_ :
                ∀ (A : Matrix n n (DualNumber R)),
                  (fun d => of fun i j => (fst d i j, snd d i j))
                      ((fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j))) A) =
                    A),
            right_inv :=
              (_ :
                ∀ (d : DualNumber (Matrix n n R)),
                  (fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)))
                      ((fun d => of fun i j => (fst d i j, snd d i j)) d) =
                    d) }
          B)
      i✝ x✝

Next tactic:
simp_rw [snd_mul, smul_eq_mul, op_smul_eq_mul]
/-- Matrices over dual numbers and dual numbers over matrices are isomorphic. -/
@[simps]
def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Matrix n n R) where
  toFun A := ⟨of fun i j => (A i j).fst, of fun i j => (A i j).snd⟩
  invFun d := of fun i j => (d.fst i j, d.snd i j)
  left_inv A := Matrix.ext fun i j => TrivSqZeroExt.ext rfl rfl
  right_inv d := TrivSqZeroExt.ext (Matrix.ext fun i j => rfl) (Matrix.ext fun i j => rfl)
  map_mul' A B := by
    ext
    · dsimp [mul_apply]
      simp_rw [fst_sum]
      rfl
    · simp_rw [snd_mul, smul_eq_mul, op_smul_eq_mul]
      

Proof state:
case h2.a.h
R n : Type
inst✝² : CommSemiring R
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A B : Matrix n n (DualNumber R)
i✝ x✝ : n
⊢ snd (of fun i j => fst ((A * B) i j), of fun i j => snd ((A * B) i j)) i✝ x✝ =
    (fst (of fun i j => fst (A i j), of fun i j => snd (A i j)) *
          snd (of fun i j => fst (B i j), of fun i j => snd (B i j)) +
        snd (of fun i j => fst (A i j), of fun i j => snd (A i j)) *
          fst (of fun i j => fst (B i j), of fun i j => snd (B i j)))
      i✝ x✝

Next tactic:
simp only [mul_apply, snd_sum, DualNumber.snd_mul, snd_mk, of_apply, fst_mk, add_apply]
/-- Matrices over dual numbers and dual numbers over matrices are isomorphic. -/
@[simps]
def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Matrix n n R) where
  toFun A := ⟨of fun i j => (A i j).fst, of fun i j => (A i j).snd⟩
  invFun d := of fun i j => (d.fst i j, d.snd i j)
  left_inv A := Matrix.ext fun i j => TrivSqZeroExt.ext rfl rfl
  right_inv d := TrivSqZeroExt.ext (Matrix.ext fun i j => rfl) (Matrix.ext fun i j => rfl)
  map_mul' A B := by
    ext
    · dsimp [mul_apply]
      simp_rw [fst_sum]
      rfl
    · simp_rw [snd_mul, smul_eq_mul, op_smul_eq_mul]
      simp only [mul_apply, snd_sum, DualNumber.snd_mul, snd_mk, of_apply, fst_mk, add_apply]
      

Proof state:
case h2.a.h
R n : Type
inst✝² : CommSemiring R
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A B : Matrix n n (DualNumber R)
i✝ x✝ : n
⊢ (Finset.sum Finset.univ fun x => fst (A i✝ x) * snd (B x x✝) + snd (A i✝ x) * fst (B x x✝)) =
    (Finset.sum Finset.univ fun x => fst (A i✝ x) * snd (B x x✝)) +
      Finset.sum Finset.univ fun x => snd (A i✝ x) * fst (B x x✝)

Next tactic:
rw [← Finset.sum_add_distrib]
/-- Matrices over dual numbers and dual numbers over matrices are isomorphic. -/
@[simps]
def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Matrix n n R) where
  toFun A := ⟨of fun i j => (A i j).fst, of fun i j => (A i j).snd⟩
  invFun d := of fun i j => (d.fst i j, d.snd i j)
  left_inv A := Matrix.ext fun i j => TrivSqZeroExt.ext rfl rfl
  right_inv d := TrivSqZeroExt.ext (Matrix.ext fun i j => rfl) (Matrix.ext fun i j => rfl)
  map_mul' A B := by
    ext
    · dsimp [mul_apply]
      simp_rw [fst_sum]
      rfl
    · simp_rw [snd_mul, smul_eq_mul, op_smul_eq_mul]
      simp only [mul_apply, snd_sum, DualNumber.snd_mul, snd_mk, of_apply, fst_mk, add_apply]
      rw [← Finset.sum_add_distrib]
  map_add' A B := TrivSqZeroExt.ext rfl rfl
  commutes' r := by
    

Proof state:
R n : Type
inst✝² : CommSemiring R
inst✝¹ : Fintype n
inst✝ : DecidableEq n
r : R
⊢ Equiv.toFun
      { toFun := fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)),
        invFun := fun d => of fun i j => (fst d i j, snd d i j),
        left_inv :=
          (_ :
            ∀ (A : Matrix n n (DualNumber R)),
              (fun d => of fun i j => (fst d i j, snd d i j))
                  ((fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j))) A) =
                A),
        right_inv :=
          (_ :
            ∀ (d : DualNumber (Matrix n n R)),
              (fun A => (of fun i j => fst (A i j), of fun i j => snd (A i j)))
                  ((fun d => of fun i j => (fst d i j, snd d i j)) d) =
                d) }
      ((algebraMap R (Matrix n n (DualNumber R))) r) =
    (algebraMap R (DualNumber (Matrix n n R))) r

Next tactic:
simp_rw [algebraMap_eq_inl', algebraMap_eq_diagonal, Pi.algebraMap_def,
      Algebra.id.map_eq_self, algebraMap_eq_inl, ← diagonal_map (inl_zero R), map_apply, fst_inl,
      snd_inl]
/-- Matrices over dual numbers and dual numbers over matrices are isomorphic. -/
@[simps]
def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Matrix n n R) where
  toFun A := ⟨of fun i j => (A i j).fst, of fun i j => (A i j).snd⟩
  invFun d := of fun i j => (d.fst i j, d.snd i j)
  left_inv A := Matrix.ext fun i j => TrivSqZeroExt.ext rfl rfl
  right_inv d := TrivSqZeroExt.ext (Matrix.ext fun i j => rfl) (Matrix.ext fun i j => rfl)
  map_mul' A B := by
    ext
    · dsimp [mul_apply]
      simp_rw [fst_sum]
      rfl
    · simp_rw [snd_mul, smul_eq_mul, op_smul_eq_mul]
      simp only [mul_apply, snd_sum, DualNumber.snd_mul, snd_mk, of_apply, fst_mk, add_apply]
      rw [← Finset.sum_add_distrib]
  map_add' A B := TrivSqZeroExt.ext rfl rfl
  commutes' r := by
    simp_rw [algebraMap_eq_inl', algebraMap_eq_diagonal, Pi.algebraMap_def,
      Algebra.id.map_eq_self, algebraMap_eq_inl, ← diagonal_map (inl_zero R), map_apply, fst_inl,
      snd_inl]
    

Proof state:
R n : Type
inst✝² : CommSemiring R
inst✝¹ : Fintype n
inst✝ : DecidableEq n
r : R
⊢ (of fun i j => diagonal (fun m => r) i j, of fun i j => 0) = inl (diagonal fun m => r)

Next tactic:
rfl
theorem normBound_pos : 0 < normBound abv bS := by
  

Proof state:
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
⊢ 0 < normBound abv bS

Next tactic:
obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    ext j k
    simp [h, DMatrix.zero_apply]
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    

Proof state:
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
⊢ ∃ i j k, (Algebra.leftMulMatrix bS) (bS i) j k ≠ 0

Next tactic:
by_contra! h
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    

Proof state:
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
h : ∀ (i j k : ι), (Algebra.leftMulMatrix bS) (bS i) j k = 0
⊢ False

Next tactic:
obtain ⟨i⟩ := bS.index_nonempty
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    

Proof state:
case intro
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
h : ∀ (i j k : ι), (Algebra.leftMulMatrix bS) (bS i) j k = 0
i : ι
⊢ False

Next tactic:
apply bS.ne_zero i
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    

Proof state:
case intro
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
h : ∀ (i j k : ι), (Algebra.leftMulMatrix bS) (bS i) j k = 0
i : ι
⊢ bS i = 0

Next tactic:
apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    

Proof state:
case intro.a
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
h : ∀ (i j k : ι), (Algebra.leftMulMatrix bS) (bS i) j k = 0
i : ι
⊢ (Algebra.leftMulMatrix bS) (bS i) = 0

Next tactic:
ext j k
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    ext j k
    

Proof state:
case intro.a.a.h
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
h : ∀ (i j k : ι), (Algebra.leftMulMatrix bS) (bS i) j k = 0
i j k : ι
⊢ (Algebra.leftMulMatrix bS) (bS i) j k = OfNat.ofNat 0 j k

Next tactic:
simp [h, DMatrix.zero_apply]
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    ext j k
    simp [h, DMatrix.zero_apply]
  

Proof state:
case intro.intro.intro
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
i j k : ι
hijk : (Algebra.leftMulMatrix bS) (bS i) j k ≠ 0
⊢ 0 < normBound abv bS

Next tactic:
simp only [normBound, Algebra.smul_def, eq_natCast]
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    ext j k
    simp [h, DMatrix.zero_apply]
  simp only [normBound, Algebra.smul_def, eq_natCast]
  

Proof state:
case intro.intro.intro
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
i j k : ι
hijk : (Algebra.leftMulMatrix bS) (bS i) j k ≠ 0
⊢ 0 <
    ↑(Nat.factorial (Fintype.card ι)) *
      (↑(Fintype.card ι) *
          Finset.max'
            (Finset.image (fun ijk => abv ((Algebra.leftMulMatrix bS) (bS ijk.1) ijk.2.1 ijk.2.2)) Finset.univ)
            (_ :
              ∃ x,
                x ∈
                  Finset.image (fun ijk => abv ((Algebra.leftMulMatrix bS) (bS ijk.1) ijk.2.1 ijk.2.2)) Finset.univ)) ^
        Fintype.card ι

Next tactic:
refine' mul_pos (Int.coe_nat_pos.mpr (Nat.factorial_pos _)) _
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    ext j k
    simp [h, DMatrix.zero_apply]
  simp only [normBound, Algebra.smul_def, eq_natCast]
  refine' mul_pos (Int.coe_nat_pos.mpr (Nat.factorial_pos _)) _
  

Proof state:
case intro.intro.intro
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
i j k : ι
hijk : (Algebra.leftMulMatrix bS) (bS i) j k ≠ 0
⊢ 0 <
    (↑(Fintype.card ι) *
        Finset.max' (Finset.image (fun ijk => abv ((Algebra.leftMulMatrix bS) (bS ijk.1) ijk.2.1 ijk.2.2)) Finset.univ)
          (_ :
            ∃ x,
              x ∈ Finset.image (fun ijk => abv ((Algebra.leftMulMatrix bS) (bS ijk.1) ijk.2.1 ijk.2.2)) Finset.univ)) ^
      Fintype.card ι

Next tactic:
refine' pow_pos (mul_pos (Int.coe_nat_pos.mpr (Fintype.card_pos_iff.mpr ⟨i⟩)) _) _
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    ext j k
    simp [h, DMatrix.zero_apply]
  simp only [normBound, Algebra.smul_def, eq_natCast]
  refine' mul_pos (Int.coe_nat_pos.mpr (Nat.factorial_pos _)) _
  refine' pow_pos (mul_pos (Int.coe_nat_pos.mpr (Fintype.card_pos_iff.mpr ⟨i⟩)) _) _
  

Proof state:
case intro.intro.intro
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
i j k : ι
hijk : (Algebra.leftMulMatrix bS) (bS i) j k ≠ 0
⊢ 0 <
    Finset.max' (Finset.image (fun ijk => abv ((Algebra.leftMulMatrix bS) (bS ijk.1) ijk.2.1 ijk.2.2)) Finset.univ)
      (_ : ∃ x, x ∈ Finset.image (fun ijk => abv ((Algebra.leftMulMatrix bS) (bS ijk.1) ijk.2.1 ijk.2.2)) Finset.univ)

Next tactic:
refine' lt_of_lt_of_le (abv.pos hijk) (Finset.le_max' _ _ _)
theorem normBound_pos : 0 < normBound abv bS := by
  obtain ⟨i, j, k, hijk⟩ : ∃ i j k, Algebra.leftMulMatrix bS (bS i) j k ≠ 0 := by
    by_contra! h
    obtain ⟨i⟩ := bS.index_nonempty
    apply bS.ne_zero i
    apply
      (injective_iff_map_eq_zero (Algebra.leftMulMatrix bS)).mp (Algebra.leftMulMatrix_injective bS)
    ext j k
    simp [h, DMatrix.zero_apply]
  simp only [normBound, Algebra.smul_def, eq_natCast]
  refine' mul_pos (Int.coe_nat_pos.mpr (Nat.factorial_pos _)) _
  refine' pow_pos (mul_pos (Int.coe_nat_pos.mpr (Fintype.card_pos_iff.mpr ⟨i⟩)) _) _
  refine' lt_of_lt_of_le (abv.pos hijk) (Finset.le_max' _ _ _)
  

Proof state:
case intro.intro.intro
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
i j k : ι
hijk : (Algebra.leftMulMatrix bS) (bS i) j k ≠ 0
⊢ abv ((Algebra.leftMulMatrix bS) (bS i) j k) ∈
    Finset.image (fun ijk => abv ((Algebra.leftMulMatrix bS) (bS ijk.1) ijk.2.1 ijk.2.2)) Finset.univ

Next tactic:
exact Finset.mem_image.mpr ⟨⟨i, j, k⟩, Finset.mem_univ _, rfl⟩
/-- If the `R`-integral element `a : S` has coordinates `≤ y` with respect to some basis `b`,
its norm is less than `normBound abv b * y ^ dim S`. -/
theorem norm_le (a : S) {y : ℤ} (hy : ∀ k, abv (bS.repr a k) ≤ y) :
    abv (Algebra.norm R a) ≤ normBound abv bS * y ^ Fintype.card ι := by
  

Proof state:
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
a : S
y : ℤ
hy : ∀ (k : ι), abv ((bS.repr a) k) ≤ y
⊢ abv ((Algebra.norm R) a) ≤ normBound abv bS * y ^ Fintype.card ι

Next tactic:
conv_lhs => rw [← bS.sum_repr a]
/-- If the `R`-integral element `a : S` has coordinates `≤ y` with respect to some basis `b`,
its norm is less than `normBound abv b * y ^ dim S`. -/
theorem norm_le (a : S) {y : ℤ} (hy : ∀ k, abv (bS.repr a k) ≤ y) :
    abv (Algebra.norm R a) ≤ normBound abv bS * y ^ Fintype.card ι := by
  conv_lhs => 

Proof state:
R : Type u_1
S : Type u_2
K : Type u_3
L : Type u_4
inst✝¹⁴ : EuclideanDomain R
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Algebra R K
inst✝⁸ : IsFractionRing R K
inst✝⁷ : Algebra K L
inst✝⁶ : FiniteDimensional K L
inst✝⁵ : IsSeparable K L
algRL : Algebra R L
inst✝⁴ : IsScalarTower R K L
inst✝³ : Algebra R S
inst✝² : Algebra S L
ist : IsScalarTower R S L
iic : IsIntegralClosure S R L
abv : AbsoluteValue R ℤ
ι : Type u_5
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
bS : Basis ι R S
a : S
y : ℤ
hy : ∀ (k : ι), abv ((bS.repr a) k) ≤ y
| abv ((Algebra.norm R) a)

Next tactic:
rw [← bS.sum_repr a]