l3lab/ntp-mathlib huggingface dataset:
/-- Let `e : S ≃ I` be an additive isomorphism (therefore a `ℤ`-linear equiv).
Then an alternative way to compute the norm of `I` is given by taking the determinant of `e`.
See `natAbs_det_basis_change` for a more familiar formulation of this result. -/
theorem natAbs_det_equiv (I : Ideal S) {E : Type*} [AddEquivClass E S I] (e : E) :
    Int.natAbs
        (LinearMap.det
          ((Submodule.subtype I).restrictScalars ℤ ∘ₗ AddMonoidHom.toIntLinearMap (e : S →+ I))) =
      Ideal.absNorm I := by
  -- `S ⧸ I` might be infinite if `I = ⊥`, but then `e` can't be an equiv.
  by_cases hI : I = ⊥
  · subst hI
    have : (1 : S) ≠ 0 := one_ne_zero
    have : (1 : S) = 0 := EquivLike.injective e (Subsingleton.elim _ _)
    contradiction
  let ι := Module.Free.ChooseBasisIndex ℤ S
  let b := Module.Free.chooseBasis ℤ S
  cases isEmpty_or_nonempty ι
  · nontriviality S
    exact (not_nontrivial_iff_subsingleton.mpr
      (Function.Surjective.subsingleton b.repr.toEquiv.symm.surjective) (by infer_instance)).elim
  -- Thus `(S ⧸ I)` is isomorphic to a product of `ZMod`s, so it is a fintype.
  letI := Ideal.fintypeQuotientOfFreeOfNeBot I hI
  -- Use the Smith normal form to choose a nice basis for `I`.
  letI := Classical.decEq ι
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  let e' : S ≃ₗ[ℤ] I := b'.equiv ab (Equiv.refl _)
  let f : S →ₗ[ℤ] S := (I.subtype.restrictScalars ℤ).comp (e' : S →ₗ[ℤ] I)
  let f_apply : ∀ x, f x = b'.equiv ab (Equiv.refl _) x := fun x => rfl
  

Proof state:
case neg.inr
S : Type u_1
inst✝⁶ : CommRing S
inst✝⁵ : IsDomain S
inst✝⁴ : Infinite S
inst✝³ : IsDedekindDomain S
inst✝² : Module.Free ℤ S
inst✝¹ : Module.Finite ℤ S
I : Ideal S
E : Type u_2
inst✝ : AddEquivClass E S ↥I
e : E
hI : ¬I = ⊥
ι : Type u_1 := Module.Free.ChooseBasisIndex ℤ S
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
h✝ : Nonempty ι
this✝ : Fintype (S ⧸ I) := fintypeQuotientOfFreeOfNeBot I hI
this : DecidableEq ι := Classical.decEq ι
a : Module.Free.ChooseBasisIndex ℤ S → ℤ := smithCoeffs b I hI
b' : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := ringBasis b I hI
ab : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ ↥I := selfBasis b I hI
ab_eq : ∀ (i : Module.Free.ChooseBasisIndex ℤ S), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
e' : S ≃ₗ[ℤ] ↥I := Basis.equiv b' ab (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))
f : S →ₗ[ℤ] S := ↑ℤ (Submodule.subtype I) ∘ₗ ↑e'
f_apply : ∀ (x : S), f x = ↑((Basis.equiv b' ab (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))) x) := fun x => rfl
⊢ Int.natAbs (LinearMap.det (↑ℤ (Submodule.subtype I) ∘ₗ AddMonoidHom.toIntLinearMap ↑e)) = absNorm I

Next tactic:
suffices (LinearMap.det f).natAbs = Ideal.absNorm I by
    calc
      _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ
            (AddEquiv.toIntLinearEquiv e : S ≃ₗ[ℤ] I))).natAbs := rfl
      _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ _)).natAbs :=
            Int.natAbs_eq_iff_associated.mpr (LinearMap.associated_det_comp_equiv _ _ _)
      _ = absNorm I := this
/-- Let `e : S ≃ I` be an additive isomorphism (therefore a `ℤ`-linear equiv).
Then an alternative way to compute the norm of `I` is given by taking the determinant of `e`.
See `natAbs_det_basis_change` for a more familiar formulation of this result. -/
theorem natAbs_det_equiv (I : Ideal S) {E : Type*} [AddEquivClass E S I] (e : E) :
    Int.natAbs
        (LinearMap.det
          ((Submodule.subtype I).restrictScalars ℤ ∘ₗ AddMonoidHom.toIntLinearMap (e : S →+ I))) =
      Ideal.absNorm I := by
  -- `S ⧸ I` might be infinite if `I = ⊥`, but then `e` can't be an equiv.
  by_cases hI : I = ⊥
  · subst hI
    have : (1 : S) ≠ 0 := one_ne_zero
    have : (1 : S) = 0 := EquivLike.injective e (Subsingleton.elim _ _)
    contradiction
  let ι := Module.Free.ChooseBasisIndex ℤ S
  let b := Module.Free.chooseBasis ℤ S
  cases isEmpty_or_nonempty ι
  · nontriviality S
    exact (not_nontrivial_iff_subsingleton.mpr
      (Function.Surjective.subsingleton b.repr.toEquiv.symm.surjective) (by infer_instance)).elim
  -- Thus `(S ⧸ I)` is isomorphic to a product of `ZMod`s, so it is a fintype.
  letI := Ideal.fintypeQuotientOfFreeOfNeBot I hI
  -- Use the Smith normal form to choose a nice basis for `I`.
  letI := Classical.decEq ι
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  let e' : S ≃ₗ[ℤ] I := b'.equiv ab (Equiv.refl _)
  let f : S →ₗ[ℤ] S := (I.subtype.restrictScalars ℤ).comp (e' : S →ₗ[ℤ] I)
  let f_apply : ∀ x, f x = b'.equiv ab (Equiv.refl _) x := fun x => rfl
  suffices (LinearMap.det f).natAbs = Ideal.absNorm I by
    

Proof state:
S : Type u_1
inst✝⁶ : CommRing S
inst✝⁵ : IsDomain S
inst✝⁴ : Infinite S
inst✝³ : IsDedekindDomain S
inst✝² : Module.Free ℤ S
inst✝¹ : Module.Finite ℤ S
I : Ideal S
E : Type u_2
inst✝ : AddEquivClass E S ↥I
e : E
hI : ¬I = ⊥
ι : Type u_1 := Module.Free.ChooseBasisIndex ℤ S
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
h✝ : Nonempty ι
this✝¹ : Fintype (S ⧸ I) := fintypeQuotientOfFreeOfNeBot I hI
this✝ : DecidableEq ι := Classical.decEq ι
a : Module.Free.ChooseBasisIndex ℤ S → ℤ := smithCoeffs b I hI
b' : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := ringBasis b I hI
ab : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ ↥I := selfBasis b I hI
ab_eq : ∀ (i : Module.Free.ChooseBasisIndex ℤ S), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
e' : S ≃ₗ[ℤ] ↥I := Basis.equiv b' ab (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))
f : S →ₗ[ℤ] S := ↑ℤ (Submodule.subtype I) ∘ₗ ↑e'
f_apply : ∀ (x : S), f x = ↑((Basis.equiv b' ab (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))) x) := fun x => rfl
this : Int.natAbs (LinearMap.det f) = absNorm I
⊢ Int.natAbs (LinearMap.det (↑ℤ (Submodule.subtype I) ∘ₗ AddMonoidHom.toIntLinearMap ↑e)) = absNorm I

Next tactic:
calc
      _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ
            (AddEquiv.toIntLinearEquiv e : S ≃ₗ[ℤ] I))).natAbs := rfl
      _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ _)).natAbs :=
            Int.natAbs_eq_iff_associated.mpr (LinearMap.associated_det_comp_equiv _ _ _)
      _ = absNorm I := this
/-- Let `e : S ≃ I` be an additive isomorphism (therefore a `ℤ`-linear equiv).
Then an alternative way to compute the norm of `I` is given by taking the determinant of `e`.
See `natAbs_det_basis_change` for a more familiar formulation of this result. -/
theorem natAbs_det_equiv (I : Ideal S) {E : Type*} [AddEquivClass E S I] (e : E) :
    Int.natAbs
        (LinearMap.det
          ((Submodule.subtype I).restrictScalars ℤ ∘ₗ AddMonoidHom.toIntLinearMap (e : S →+ I))) =
      Ideal.absNorm I := by
  -- `S ⧸ I` might be infinite if `I = ⊥`, but then `e` can't be an equiv.
  by_cases hI : I = ⊥
  · subst hI
    have : (1 : S) ≠ 0 := one_ne_zero
    have : (1 : S) = 0 := EquivLike.injective e (Subsingleton.elim _ _)
    contradiction
  let ι := Module.Free.ChooseBasisIndex ℤ S
  let b := Module.Free.chooseBasis ℤ S
  cases isEmpty_or_nonempty ι
  · nontriviality S
    exact (not_nontrivial_iff_subsingleton.mpr
      (Function.Surjective.subsingleton b.repr.toEquiv.symm.surjective) (by infer_instance)).elim
  -- Thus `(S ⧸ I)` is isomorphic to a product of `ZMod`s, so it is a fintype.
  letI := Ideal.fintypeQuotientOfFreeOfNeBot I hI
  -- Use the Smith normal form to choose a nice basis for `I`.
  letI := Classical.decEq ι
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  let e' : S ≃ₗ[ℤ] I := b'.equiv ab (Equiv.refl _)
  let f : S →ₗ[ℤ] S := (I.subtype.restrictScalars ℤ).comp (e' : S →ₗ[ℤ] I)
  let f_apply : ∀ x, f x = b'.equiv ab (Equiv.refl _) x := fun x => rfl
  suffices (LinearMap.det f).natAbs = Ideal.absNorm I by
    calc
      _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ
            (AddEquiv.toIntLinearEquiv e : S ≃ₗ[ℤ] I))).natAbs := rfl
      _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ _)).natAbs :=
            Int.natAbs_eq_iff_associated.mpr (LinearMap.associated_det_comp_equiv _ _ _)
      _ = absNorm I := this
  have ha : ∀ i, f (b' i) = a i • b' i := by
    

Proof state:
S : Type u_1
inst✝⁶ : CommRing S
inst✝⁵ : IsDomain S
inst✝⁴ : Infinite S
inst✝³ : IsDedekindDomain S
inst✝² : Module.Free ℤ S
inst✝¹ : Module.Finite ℤ S
I : Ideal S
E : Type u_2
inst✝ : AddEquivClass E S ↥I
e : E
hI : ¬I = ⊥
ι : Type u_1 := Module.Free.ChooseBasisIndex ℤ S
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
h✝ : Nonempty ι
this✝ : Fintype (S ⧸ I) := fintypeQuotientOfFreeOfNeBot I hI
this : DecidableEq ι := Classical.decEq ι
a : Module.Free.ChooseBasisIndex ℤ S → ℤ := smithCoeffs b I hI
b' : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := ringBasis b I hI
ab : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ ↥I := selfBasis b I hI
ab_eq : ∀ (i : Module.Free.ChooseBasisIndex ℤ S), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
e' : S ≃ₗ[ℤ] ↥I := Basis.equiv b' ab (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))
f : S →ₗ[ℤ] S := ↑ℤ (Submodule.subtype I) ∘ₗ ↑e'
f_apply : ∀ (x : S), f x = ↑((Basis.equiv b' ab (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))) x) := fun x => rfl
⊢ ∀ (i : Module.Free.ChooseBasisIndex ℤ S), f (b' i) = a i • b' i

Next tactic:
intro i
/-- Let `b` be a basis for `S` over `ℤ` and `bI` a basis for `I` over `ℤ` of the same dimension.
Then an alternative way to compute the norm of `I` is given by taking the determinant of `bI`
over `b`. -/
theorem natAbs_det_basis_change {ι : Type*} [Fintype ι] [DecidableEq ι] (b : Basis ι ℤ S)
    (I : Ideal S) (bI : Basis ι ℤ I) : (b.det ((↑) ∘ bI)).natAbs = Ideal.absNorm I := by
  

Proof state:
S : Type u_1
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Infinite S
inst✝⁴ : IsDedekindDomain S
inst✝³ : Module.Free ℤ S
inst✝² : Module.Finite ℤ S
ι : Type u_2
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
b : Basis ι ℤ S
I : Ideal S
bI : Basis ι ℤ ↥I
⊢ Int.natAbs ((Basis.det b) (Subtype.val ∘ ⇑bI)) = absNorm I

Next tactic:
let e := b.equiv bI (Equiv.refl _)
/-- Let `b` be a basis for `S` over `ℤ` and `bI` a basis for `I` over `ℤ` of the same dimension.
Then an alternative way to compute the norm of `I` is given by taking the determinant of `bI`
over `b`. -/
theorem natAbs_det_basis_change {ι : Type*} [Fintype ι] [DecidableEq ι] (b : Basis ι ℤ S)
    (I : Ideal S) (bI : Basis ι ℤ I) : (b.det ((↑) ∘ bI)).natAbs = Ideal.absNorm I := by
  let e := b.equiv bI (Equiv.refl _)
  

Proof state:
S : Type u_1
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Infinite S
inst✝⁴ : IsDedekindDomain S
inst✝³ : Module.Free ℤ S
inst✝² : Module.Finite ℤ S
ι : Type u_2
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
b : Basis ι ℤ S
I : Ideal S
bI : Basis ι ℤ ↥I
e : S ≃ₗ[ℤ] ↥I := Basis.equiv b bI (Equiv.refl ι)
⊢ Int.natAbs ((Basis.det b) (Subtype.val ∘ ⇑bI)) = absNorm I

Next tactic:
calc
    (b.det ((Submodule.subtype I).restrictScalars ℤ ∘ bI)).natAbs =
        (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ (e : S →ₗ[ℤ] I))).natAbs :=
      by rw [Basis.det_comp_basis]
    _ = _ := natAbs_det_equiv I e
/-- Let `b` be a basis for `S` over `ℤ` and `bI` a basis for `I` over `ℤ` of the same dimension.
Then an alternative way to compute the norm of `I` is given by taking the determinant of `bI`
over `b`. -/
theorem natAbs_det_basis_change {ι : Type*} [Fintype ι] [DecidableEq ι] (b : Basis ι ℤ S)
    (I : Ideal S) (bI : Basis ι ℤ I) : (b.det ((↑) ∘ bI)).natAbs = Ideal.absNorm I := by
  let e := b.equiv bI (Equiv.refl _)
  calc
    (b.det ((Submodule.subtype I).restrictScalars ℤ ∘ bI)).natAbs =
        (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ (e : S →ₗ[ℤ] I))).natAbs :=
      by 

Proof state:
S : Type u_1
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Infinite S
inst✝⁴ : IsDedekindDomain S
inst✝³ : Module.Free ℤ S
inst✝² : Module.Finite ℤ S
ι : Type u_2
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
b : Basis ι ℤ S
I : Ideal S
bI : Basis ι ℤ ↥I
e : S ≃ₗ[ℤ] ↥I := Basis.equiv b bI (Equiv.refl ι)
⊢ Int.natAbs ((Basis.det b) (⇑(↑ℤ (Submodule.subtype I)) ∘ ⇑bI)) =
    Int.natAbs (LinearMap.det (↑ℤ (Submodule.subtype I) ∘ₗ ↑e))

Next tactic:
rw [Basis.det_comp_basis]
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  

Proof state:
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
⊢ absNorm (span {r}) = Int.natAbs ((Algebra.norm ℤ) r)

Next tactic:
rw [Algebra.norm_apply]
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  

Proof state:
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
⊢ absNorm (span {r}) = Int.natAbs (LinearMap.det ((Algebra.lmul ℤ S) r))

Next tactic:
by_cases hr : r = 0
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  by_cases hr : r = 0
  · 

Proof state:
case pos
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
hr : r = 0
⊢ absNorm (span {r}) = Int.natAbs (LinearMap.det ((Algebra.lmul ℤ S) r))

Next tactic:
simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  by_cases hr : r = 0
  · simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
  

Proof state:
case neg
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
hr : ¬r = 0
⊢ absNorm (span {r}) = Int.natAbs (LinearMap.det ((Algebra.lmul ℤ S) r))

Next tactic:
letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  by_cases hr : r = 0
  · simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
  

Proof state:
case neg
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
hr : ¬r = 0
this : Fintype (S ⧸ span {r}) := fintypeQuotientOfFreeOfNeBot (span {r}) (_ : ¬span {r} = ⊥)
⊢ absNorm (span {r}) = Int.natAbs (LinearMap.det ((Algebra.lmul ℤ S) r))

Next tactic:
let b := Module.Free.chooseBasis ℤ S
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  by_cases hr : r = 0
  · simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
  let b := Module.Free.chooseBasis ℤ S
  

Proof state:
case neg
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
hr : ¬r = 0
this : Fintype (S ⧸ span {r}) := fintypeQuotientOfFreeOfNeBot (span {r}) (_ : ¬span {r} = ⊥)
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
⊢ absNorm (span {r}) = Int.natAbs (LinearMap.det ((Algebra.lmul ℤ S) r))

Next tactic:
rw [← natAbs_det_equiv _ (b.equiv (basisSpanSingleton b hr) (Equiv.refl _))]
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  by_cases hr : r = 0
  · simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
  let b := Module.Free.chooseBasis ℤ S
  rw [← natAbs_det_equiv _ (b.equiv (basisSpanSingleton b hr) (Equiv.refl _))]
  

Proof state:
case neg
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
hr : ¬r = 0
this : Fintype (S ⧸ span {r}) := fintypeQuotientOfFreeOfNeBot (span {r}) (_ : ¬span {r} = ⊥)
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
⊢ Int.natAbs
      (LinearMap.det
        (↑ℤ (Submodule.subtype (span {r})) ∘ₗ
          AddMonoidHom.toIntLinearMap
            ↑(Basis.equiv b (basisSpanSingleton b hr) (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))))) =
    Int.natAbs (LinearMap.det ((Algebra.lmul ℤ S) r))

Next tactic:
congr
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  by_cases hr : r = 0
  · simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
  let b := Module.Free.chooseBasis ℤ S
  rw [← natAbs_det_equiv _ (b.equiv (basisSpanSingleton b hr) (Equiv.refl _))]
  congr
  

Proof state:
case neg.e_m.h.e_6.h
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
hr : ¬r = 0
this : Fintype (S ⧸ span {r}) := fintypeQuotientOfFreeOfNeBot (span {r}) (_ : ¬span {r} = ⊥)
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
⊢ ↑ℤ (Submodule.subtype (span {r})) ∘ₗ
      AddMonoidHom.toIntLinearMap
        ↑(Basis.equiv b (basisSpanSingleton b hr) (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))) =
    (Algebra.lmul ℤ S) r

Next tactic:
refine b.ext fun i => ?_
@[simp]
theorem absNorm_span_singleton (r : S) :
    absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs := by
  rw [Algebra.norm_apply]
  by_cases hr : r = 0
  · simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
  let b := Module.Free.chooseBasis ℤ S
  rw [← natAbs_det_equiv _ (b.equiv (basisSpanSingleton b hr) (Equiv.refl _))]
  congr
  refine b.ext fun i => ?_
  

Proof state:
case neg.e_m.h.e_6.h
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
hr : ¬r = 0
this : Fintype (S ⧸ span {r}) := fintypeQuotientOfFreeOfNeBot (span {r}) (_ : ¬span {r} = ⊥)
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
i : Module.Free.ChooseBasisIndex ℤ S
⊢ (↑ℤ (Submodule.subtype (span {r})) ∘ₗ
        AddMonoidHom.toIntLinearMap
          ↑(Basis.equiv b (basisSpanSingleton b hr) (Equiv.refl (Module.Free.ChooseBasisIndex ℤ S))))
      (b i) =
    ((Algebra.lmul ℤ S) r) (b i)

Next tactic:
simp
theorem absNorm_dvd_norm_of_mem {I : Ideal S} {x : S} (h : x ∈ I) :
    ↑(Ideal.absNorm I) ∣ Algebra.norm ℤ x := by
  

Proof state:
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
x : S
h : x ∈ I
⊢ ↑(absNorm I) ∣ (Algebra.norm ℤ) x

Next tactic:
rw [← Int.dvd_natAbs, ← absNorm_span_singleton x, Int.coe_nat_dvd]
theorem absNorm_dvd_norm_of_mem {I : Ideal S} {x : S} (h : x ∈ I) :
    ↑(Ideal.absNorm I) ∣ Algebra.norm ℤ x := by
  rw [← Int.dvd_natAbs, ← absNorm_span_singleton x, Int.coe_nat_dvd]
  

Proof state:
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
x : S
h : x ∈ I
⊢ absNorm I ∣ absNorm (span {x})

Next tactic:
exact absNorm_dvd_absNorm_of_le ((span_singleton_le_iff_mem _).mpr h)
@[simp]
theorem absNorm_span_insert (r : S) (s : Set S) :
    absNorm (span (insert r s)) ∣ gcd (absNorm (span s)) (Algebra.norm ℤ r).natAbs :=
  (dvd_gcd_iff _ _ _).mpr
    ⟨absNorm_dvd_absNorm_of_le (span_mono (Set.subset_insert _ _)),
      _root_.trans
        (absNorm_dvd_absNorm_of_le (span_mono (Set.singleton_subset_iff.mpr (Set.mem_insert _ _))))
        (by 

Proof state:
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
r : S
s : Set S
⊢ absNorm (span {r}) ∣ Int.natAbs ((Algebra.norm ℤ) r)

Next tactic:
rw [absNorm_span_singleton]
theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := by
  

Proof state:
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
⊢ absNorm I = 0 ↔ I = ⊥

Next tactic:
constructor
theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := by
  constructor
  · 

Proof state:
case mp
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
⊢ absNorm I = 0 → I = ⊥

Next tactic:
intro hI
theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := by
  constructor
  · intro hI
    

Proof state:
case mp
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : absNorm I = 0
⊢ I = ⊥

Next tactic:
rw [← le_bot_iff]
theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := by
  constructor
  · intro hI
    rw [← le_bot_iff]
    

Proof state:
case mp
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : absNorm I = 0
⊢ I ≤ ⊥

Next tactic:
intros x hx
theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := by
  constructor
  · intro hI
    rw [← le_bot_iff]
    intros x hx
    

Proof state:
case mp
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : absNorm I = 0
x : S
hx : x ∈ I
⊢ x ∈ ⊥

Next tactic:
rw [mem_bot, ← Algebra.norm_eq_zero_iff (R := ℤ), ← Int.natAbs_eq_zero,
      ← Ideal.absNorm_span_singleton, ← zero_dvd_iff, ← hI]
theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := by
  constructor
  · intro hI
    rw [← le_bot_iff]
    intros x hx
    rw [mem_bot, ← Algebra.norm_eq_zero_iff (R := ℤ), ← Int.natAbs_eq_zero,
      ← Ideal.absNorm_span_singleton, ← zero_dvd_iff, ← hI]
    

Proof state:
case mp
S : Type u_1
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Infinite S
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : absNorm I = 0
x : S
hx : x ∈ I
⊢ absNorm I ∣ absNorm (span {x})

Next tactic:
apply Ideal.absNorm_dvd_absNorm_of_le